Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do template aliases affect template parameter deduction?

In C++03, template parameter deduction does not occur in some contexts. For example:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
void f(typename A<T>::type);

int main()
{
    B<int> b;
    f(b);  // ERROR: no match
}

Here, int is not deduced for T, because a nested type such as A<T>::type is a non-deduced context.

Had I written the function like this:

template <typename T> struct B {};

template <typename T>
void f(B<T>);

int main()
{
    B<int> b;
    f(b);
}

everything is fine because B<T> is a deduced context.

In C++11, however, template aliases can be used to disguise a nested type in syntax similar to the second example. For example:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
using C = typename A<T>::type;

template <typename T>
void f(C<T>);

int main()
{
    B<int> b;
    f(b);
}

Would template argument deduction work in this case? In other words, are template aliases a deduced context or a non-deduced context? Or do they inherit the deduced/non-deduced status of whatever they alias?

like image 700
HighCommander4 Avatar asked Jan 08 '12 03:01

HighCommander4


People also ask

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What is correct for template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

What is template type alias?

Type alias is a name that refers to a previously defined type (similar to typedef). Alias template is a name that refers to a family of types.


1 Answers

Imagine this:

template <typename T> struct Foo { typedef   T type; }
template <> struct Foo<char>     { typedef int type; }

template <typename T> using mytype = typename Foo<T>::type;

template <typename T> void f(mytype<T>);

Now if I want int n; f(n);, how could I decide whether I want T = int or T = char? The whole problem, which is unaffected by template aliases, is that you cannot deduce backwards to all the things that could possibly define something.

like image 141
Kerrek SB Avatar answered Oct 16 '22 15:10

Kerrek SB