14 Templates [temp]

14.5 Template declarations [temp.decls]

A template-id, that is, the template-name followed by a template-argument-list shall not be specified in the declaration of a primary template declaration. [ Example:

template<class T1, class T2, int I> class A<T1, T2, I> { };     // error
template<class T1, int I> void sort<T1, I>(T1 data[I]);         // error

 — end example ] [ Note: However, this syntax is allowed in class template partial specializations ([temp.class.spec]).  — end note ]

For purposes of name lookup and instantiation, default arguments of function templates and default arguments of member functions of class templates are considered definitions; each default argument is a separate definition which is unrelated to the function template definition or to any other default arguments.

Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.

14.5.1 Class templates [temp.class]

A class template defines the layout and operations for an unbounded set of related types. [ Example: a single class template List might provide a common definition for list of int, list of float, and list of pointers to Shapes.  — end example ]

Example: An array class template might be declared like this:

template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};

The prefix template <class T> specifies that a template is being declared and that a type-name T will be used in the declaration. In other words, Array is a parameterized type with T as its parameter.  — end example ]

When a member function, a member class, a member enumeration, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-parameters are those of the class template. The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition. The template argument list following the class template name in the member definition shall name the parameters in the same order as the one used in the template parameter list of the member. Each template parameter pack shall be expanded with an ellipsis in the template argument list. [ Example:

template<class T1, class T2> struct A {
  void f1();
  void f2();
};

template<class T2, class T1> void A<T2,T1>::f1() { }    // OK
template<class T2, class T1> void A<T1,T2>::f2() { }    // error
template<class ... Types> struct B {
  void f3();
  void f4();
};

template<class ... Types> void B<Types ...>::f3() { }    // OK
template<class ... Types> void B<Types>::f4() { }        // error

 — end example ]

In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration ([dcl.type.elab]).

14.5.1.1 Member functions of class templates [temp.mem.func]

A member function of a class template may be defined outside of the class template definition in which it is declared. [ Example:

template<class T> class Array {
  T* v;
  int sz;
public:
  explicit Array(int);
  T& operator[](int);
  T& elem(int i) { return v[i]; }
};

declares three function templates. The subscript function might be defined like this:

template<class T> T& Array<T>::operator[](int i) {
  if (i<0 || sz<=i) error("Array: range error");
  return v[i];
}

 — end example ]

The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called. [ Example: the template-argument for Array<T> :: operator [] () will be determined by the Array to which the subscripting operation is applied.

Array<int> v1(20);
Array<dcomplex> v2(30);

v1[3] = 7;                      // Array<int>::operator[]()
v2[3] = dcomplex(7,8);          // Array<dcomplex>::operator[]()

 — end example ]

14.5.1.2 Member classes of class templates [temp.mem.class]

A class member of a class template may be defined outside the class template definition in which it is declared. [ Note: The class member must be defined before its first use that requires an instantiation ([temp.inst]). For example,

template<class T> struct A {
  class B;
};
A<int>::B* b1;                  // OK: requires A to be defined but not A::B
template<class T> class A<T>::B { };
A<int>::B  b2;                  // OK: requires A::B to be defined

 — end note ]

14.5.1.3 Static data members of class templates [temp.static]

A definition for a static data member may be provided in a namespace scope enclosing the definition of the static member's class template. [ Example:

template<class T> class X {
  static T s;
};
template<class T> T X<T>::s = 0;

 — end example ]

An explicit specialization of a static data member declared as an array of unknown bound can have a different bound from its definition, if any. [ Example:

template <class T> struct A {
  static int i[];
};
template <class T> int A<T>::i[4];    // 4 elements
template <> int A<int>::i[] = { 1 };  // OK: 1 element

 — end example ]

14.5.1.4 Enumeration members of class templates [temp.mem.enum]

An enumeration member of a class template may be defined outside the class template definition. [ Example:

template<class T> struct A {
  enum E : T;
};
A<int> a;
template<class T> enum A<T>::E : T { e1, e2 };
A<int>::E e = A<int>::e1;

 — end example ]

14.5.2 Member templates [temp.mem]

A template can be declared within a class or class template; such a template is called a member template. A member template can be defined within or outside its class definition or class template definition. A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template. [ Example:

template<class T> struct string {
  template<class T2> int compare(const T2&);
  template<class T2> string(const string<T2>& s) { /* ... */ }
};

template<class T> template<class T2> int string<T>::compare(const T2& s) {
}

 — end example ]

A local class shall not have member templates. Access control rules (Clause [class.access]) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied. [ Example:

template <class T> struct A {
  void f(int);
  template <class T2> void f(T2);
};

template <> void A<int>::f(int) { }                     // non-template member
template <> template <> void A<int>::f<>(int) { }       // template member

int main() {
  A<char> ac;
  ac.f(1);          // non-template
  ac.f('c');        // template
  ac.f<>(1);        // template
}

 — end example ]

A member function template shall not be virtual. [ Example:

template <class T> struct AA {
  template <class C> virtual void g(C);   // error
  virtual void f();                       // OK
};

 — end example ]

A specialization of a member function template does not override a virtual function from a base class. [ Example:

class B {
  virtual void f(int);
};

class D : public B {
  template <class T> void f(T); // does not override B::f(int)
  void f(int i) { f<>(i); }     // overriding function that calls
                                // the template instantiation
};

 — end example ]

A specialization of a conversion function template is referenced in the same way as a non-template conversion function that converts to the same type. [ Example:

struct A {
  template <class T> operator T*();
};
template <class T> A::operator T*(){ return 0; }
template <> A::operator char*(){ return 0; }    // specialization
template A::operator void*();                   // explicit instantiation

int main() {
  A a;
  int *ip;
  ip = a.operator int*();       // explicit call to template operator
                                // A::operator int*()
}

 — end example ] [ Note: Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates.  — end note ]

A specialization of a conversion function template is not found by name lookup. Instead, any conversion function templates visible in the context of the use are considered. For each such operator, if argument deduction succeeds ([temp.deduct.conv]), the resulting specialization is used as if found by name lookup.

A using-declaration in a derived class cannot refer to a specialization of a conversion function template in a base class.

Overload resolution ([over.ics.rank]) and partial ordering ([temp.func.order]) are used to select the best conversion function among multiple specializations of conversion function templates and/or non-template conversion functions.

14.5.3 Variadic templates [temp.variadic]

A template parameter pack is a template parameter that accepts zero or more template arguments. [ Example:

template<class ... Types> struct Tuple { };

Tuple<> t0;                     // Types contains no arguments
Tuple<int> t1;                  // Types contains one argument: int
Tuple<int, float> t2;           // Types contains two arguments: int and float
Tuple<0> error;                 // error: 0 is not a type

 — end example ]

A function parameter pack is a function parameter that accepts zero or more function arguments. [ Example:

template<class ... Types> void f(Types ... args);

f();                // OK: args contains no arguments
f(1);               // OK: args contains one argument: int
f(2, 1.0);          // OK: args contains two arguments: int and double

 — end example ]

A parameter pack is either a template parameter pack or a function parameter pack.

A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list (described below). The form of the pattern depends on the context in which the expansion occurs. Pack expansions can occur in the following contexts:

Example:

template<class ... Types> void f(Types ... rest);
template<class ... Types> void g(Types ... rest) {
  f(&rest ...);     // “&rest ...” is a pack expansion; “&rest” is its pattern
}

 — end example ]

A parameter pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion. An appearance of the name of a parameter pack is only expanded by the innermost enclosing pack expansion. The pattern of a pack expansion shall name one or more parameter packs that are not expanded by a nested pack expansion; such parameter packs are called unexpanded parameter packs in the pattern. All of the parameter packs expanded by a pack expansion shall have the same number of arguments specified. An appearance of a name of a parameter pack that is not expanded is ill-formed. [ Example:

template<typename...> struct Tuple {};
template<typename T1, typename T2> struct Pair {};

template<class ... Args1> struct zip {
  template<class ... Args2> struct with {
    typedef Tuple<Pair<Args1, Args2> ... > type;
  };
};

typedef zip<short, int>::with<unsigned short, unsigned>::type T1;
    // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>
typedef zip<short>::with<unsigned short, unsigned>::type T2;
    // error: different number of arguments specified for Args1 and Args2

template<class ... Args>
  void g(Args ... args) {               // OK: Args is expanded by the function parameter pack args
    f(const_cast<const Args*>(&args)...); // OK: “Args” and “args” are expanded
    f(5 ...);                             // error: pattern does not contain any parameter packs
    f(args);                              // error: parameter pack “args” is not expanded
    f(h(args ...) + args ...);            // OK: first “args” expanded within h, second
                                          // “args” expanded within f
  }

 — end example ]

The instantiation of a pack expansion that is not a sizeof... expression produces a list E1, E2, ..., EN, where N is the number of elements in the pack expansion parameters. Each Ei is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element. All of the Ei become elements in the enclosing list. [ Note: The variety of list varies with the context: expression-list, base-specifier-list, template-argument-list, etc. — end note ] When N is zero, the instantiation of the expansion produces an empty list. Such an instantiation does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the list entirely would otherwise be ill-formed or would result in an ambiguity in the grammar. [ Example:

template<class... T> struct X : T... { };
template<class... T> void f(T... values) {
  X<T...> x(values...);
}

template void f<>();  // OK: X<> has no base classes
                      // x is a variable of type X<> that is value-initialized

 — end example ]

The instantiation of a sizeof... expression ([expr.sizeof]) produces an integral constant containing the number of elements in the parameter pack it expands.

14.5.4 Friends [temp.friend]

A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or an ordinary (non-template) function or class. For a friend function declaration that is not a template declaration:

  • if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise

  • if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,

  • if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template ([temp.deduct.decl]), otherwise,

  • the name shall be an unqualified-id that declares (or redeclares) an ordinary (non-template) function.

Example:

template<class T> class task;
template<class T> task<T>* preempt(task<T>*);

template<class T> class task {
  friend void next_time();
  friend void process(task<T>*);
  friend task<T>* preempt<T>(task<T>*);
  template<class C> friend int func(C);

  friend class task<int>;
  template<class P> friend class frd;
};

Here, each specialization of the task class template has the function next_time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument <T>, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends. Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.  — end example ]

A friend template may be declared within a class or class template. A friend function template may be defined within a class or class template, but a friend class template may not be defined in a class or class template. In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship. [ Example:

class A {
  template<class T> friend class B;                 // OK
  template<class T> friend void f(T){ /* ... */ }  // OK
};

 — end example ]

A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([temp.inst]), partially specialized ([temp.class.spec]) or explicitly specialized ([temp.expl.spec]), are friends of the class containing the template friend declaration. [ Example:

class X {
  template<class T> friend struct A;
  class Y { };
};

template<class T> struct A { X::Y ab; };            // OK
template<class T> struct A<T*> { X::Y ab; };        // OK

 — end example ]

When a function is defined in a friend function declaration in a class template, the function is instantiated when the function is odr-used. The same restrictions on multiple declarations and definitions that apply to non-template function declarations and definitions also apply to these implicit definitions.

A member of a class template may be declared to be a friend of a non-template class. In this case, the corresponding member of every specialization of the class template is a friend of the class granting friendship. For explicit specializations the corresponding member is the member (if any) that has the same name, kind (type, function, class template, or function template), template parameters, and signature as the member of the class template instantiation that would otherwise have been generated. [ Example:

template<class T> struct A {
  struct B { };
  void f();
  struct D {
    void g();
  };
};
template<> struct A<int> {
  struct B { };
  int f();
  struct D {
    void g();
  };
};

class C {
  template<class T> friend struct A<T>::B;    // grants friendship to A<int>::B even though
                                              // it is not a specialization of A<T>::B
  template<class T> friend void A<T>::f();    // does not grant friendship to A<int>::f()
                                              // because its return type does not match
  template<class T> friend void A<T>::D::g(); // does not grant friendship to A<int>::D::g()
                                              // because A<int>::D is not a specialization of A<T>::D
};

 — end example ]

Note: A friend declaration may first declare a member of an enclosing namespace scope ([temp.inject]).  — end note ]

A friend template shall not be declared in a local class.

Friend declarations shall not declare partial specializations. [ Example:

template<class T> class A { };
class X {
  template<class T> friend class A<T*>; // error
};

 — end example ]

When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include default arguments, nor shall the inline specifier be used in such a declaration.

14.5.5 Class template partial specializations [temp.class.spec]

A primary class template declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a simple-template-id is a partial specialization of the class template named in the simple-template-id. A partial specialization of a class template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization ([temp.class.spec.match]). The primary template shall be declared before any specializations of that template. A partial specialization shall be declared before the first use of a class template specialization that would make use of the partial specialization as the result of an implicit or explicit instantiation in every translation unit in which such a use occurs; no diagnostic is required.

Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization ([temp.class.spec.mfunc]).

Example:

template<class T1, class T2, int I> class A             { };    // #1
template<class T, int I>            class A<T, T*, I>   { };    // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { };    // #3
template<class T>                   class A<int, T*, 5> { };    // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { };    // #5

The first declaration declares the primary (unspecialized) class template. The second and subsequent declarations declare partial specializations of the primary template.  — end example ]

The template parameters are specified in the angle bracket enclosed list that immediately follows the keyword template. For partial specializations, the template argument list is explicitly written immediately following the class template name. For primary templates, this list is implicitly described by the template parameter list. Specifically, the order of the template arguments is the sequence in which they appear in the template parameter list. [ Example: the template argument list for the primary template in the example above is <T1, T2, I>.  — end example ] [ Note: The template argument list shall not be specified in the primary template declaration. For example,

template<class T1, class T2, int I> class A<T1, T2, I>  { };    // error

 — end note ]

A class template partial specialization may be declared or redeclared in any namespace scope in which its definition may be defined ([temp.class] and [temp.mem]). [ Example:

template<class T> struct A {
  struct C {
    template<class T2> struct B { };
  };
};

// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
  struct A<T>::C::B<T2*> { };

A<short>::C::B<int*> absip;     // uses partial specialization

 — end example ]

Partial specialization declarations themselves are not found by name lookup. Rather, when the primary template name is used, any previously-declared partial specializations of the primary template are also considered. One consequence is that a using-declaration which refers to a class template does not restrict the set of partial specializations which may be found through the using-declaration. [ Example:

namespace N {
  template<class T1, class T2> class A { };         // primary template
}

using N::A;                             // refers to the primary template

namespace N {
  template<class T> class A<T, T*> { }; // partial specialization
}

A<int,int*> a;                  // uses the partial specialization, which is found through
                                // the using declaration which refers to the primary template

 — end example ]

A non-type argument is non-specialized if it is the name of a non-type parameter. All other non-type arguments are specialized.

Within the argument list of a class template partial specialization, the following restrictions apply:

  • A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier. [ Example:

    template <int I, int J> struct A {};
    template <int I> struct A<I+5, I*2> {}; // error
    
    template <int I, int J> struct B {};
    template <int I> struct B<I, I> {};     // OK
    

     — end example ]

  • The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ Example:

    template <class T, T t> struct C {};
    template <class T> struct C<T, 1>;                  // error
    
    template< int X, int (*array_ptr)[X] > class A {};
    int array[5];
    template< int X > class A<X,&array> { };            // error
    

     — end example ]

  • The argument list of the specialization shall not be identical to the implicit argument list of the primary template.

  • The template parameter list of a specialization shall not contain default template argument values.140

  • An argument shall not contain an unexpanded parameter pack. If an argument is a pack expansion ([temp.variadic]), it shall be the last argument in the template argument list.

There is no way in which they could be used.

14.5.5.1 Matching of class template partial specializations [temp.class.spec.match]

When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations. This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations.

  • If exactly one matching specialization is found, the instantiation is generated from that specialization.

  • If more than one matching specialization is found, the partial order rules ([temp.class.order]) are used to determine whether one of the specializations is more specialized than the others. If none of the specializations is more specialized than all of the other matching specializations, then the use of the class template is ambiguous and the program is ill-formed.

  • If no matches are found, the instantiation is generated from the primary template.

A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list ([temp.deduct]). [ Example:

A<int, int, 1>   a1;            // uses #1
A<int, int*, 1>  a2;            // uses #2, T is int, I is 1
A<int, char*, 5> a3;            // uses #4, T is char
A<int, char*, 1> a4;            // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5;            // ambiguous: matches #3 and #5

 — end example ]

A non-type template argument can also be deduced from the value of an actual template argument of a non-type parameter of the primary template. [ Example: the declaration of a2 above.  — end example ]

In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument list shall match the template parameter list of the primary template. The template arguments of a specialization are deduced from the arguments of the primary template.

14.5.5.2 Partial ordering of class template specializations [temp.class.order]

For two class template partial specializations, the first is at least as specialized as the second if, given the following rewrite to two function templates, the first function template is at least as specialized as the second according to the ordering rules for function templates ([temp.func.order]):

  • the first function template has the same template parameters as the first partial specialization and has a single function parameter whose type is a class template specialization with the template arguments of the first partial specialization, and

  • the second function template has the same template parameters as the second partial specialization and has a single function parameter whose type is a class template specialization with the template arguments of the second partial specialization.

Example:

template<int I, int J, class T> class X { };
template<int I, int J>          class X<I, J, int> { }; // #1
template<int I>                 class X<I, I, int> { }; // #2

template<int I, int J> void f(X<I, J, int>);            // A
template<int I>        void f(X<I, I, int>);            // B

The partial specialization #2 is more specialized than the partial specialization #1 because the function template B is more specialized than the function template A according to the ordering rules for function templates.  — end example ]

14.5.5.3 Members of class template specializations [temp.class.spec.mfunc]

The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization. A class template specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template. Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization. An explicit specialization of a member of a class template partial specialization is declared in the same way as an explicit specialization of the primary template. [ Example:

// primary template
template<class T, int I> struct A {
  void f();
};

template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
  void f();
  void g();
  void h();
};

// member of class template partial specialization
template<class T> void A<T,2>::g() { }

// explicit specialization
template<> void A<char,2>::h() { }

int main() {
  A<char,0> a0;
  A<char,2> a2;
  a0.f();                       // OK, uses definition of primary template's member
  a2.g();                       // OK, uses definition of
                                // partial specialization's member
  a2.h();                       // OK, uses definition of
                                // explicit specialization's member
  a2.f();                       // ill-formed, no definition of f for A<T,2>
                                // the primary template is not used here
}

 — end example ]

If a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; if the enclosing class template is instantiated ([temp.inst], [temp.explicit]), a declaration for every member template partial specialization is also instantiated as part of creating the members of the class template specialization. If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template. If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template. [ Example:

template<class T> struct A {
  template<class T2> struct B {};                     // #1
  template<class T2> struct B<T2*> {};                // #2
};

template<> template<class T2> struct A<short>::B {};  // #3

A<char>::B<int*>  abcip;  // uses #2
A<short>::B<int*> absip;  // uses #3
A<char>::B<int>  abci;    // uses #1

 — end example ]

14.5.6 Function templates [temp.fct]

A function template defines an unbounded set of related functions. [ Example: a family of sort functions might be declared like this:

template<class T> class Array { };
template<class T> void sort(Array<T>&);

 — end example ]

A function template can be overloaded with other function templates and with normal (non-template) functions. A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.141

That is, declarations of non-template functions do not merely guide overload resolution of function template specializations with the same name. If such a non-template function is odr-used ([basic.def.odr]) in a program, it must be defined; it will not be implicitly instantiated using the function template definition.

14.5.6.2 Partial ordering of function templates [temp.func.order]

If a function template is overloaded, the use of a function template specialization might be ambiguous because template argument deduction ([temp.deduct]) may associate the function template specialization with more than one function template declaration. Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:

Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process.

To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs ([temp.variadic]) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. If only one of the function templates is a non-static member, that function template is considered to have a new first parameter inserted in its function parameter list. The new parameter is of type “reference to cv A,” where cv are the cv-qualifiers of the function template (if any) and A is the class of which the function template is a member. [ Note: This allows a non-static member to be ordered with respect to a nonmember function and for the results to be equivalent to the ordering of two equivalent nonmembers.  — end note ] [ Example:

struct A { };
template<class T> struct B {
  template<class R> int operator*(R&);              // #1
};

template<class T, class R> int operator*(T&, R&);   // #2

// The declaration of B::operator* is transformed into the equivalent of
// template<class R> int operator*(B<A>&, R&);      // #1a

int main() {
  A a;
  B<A> b;
  b * a;                                            // calls #1a
}

 — end example ]

Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial].

Example:

template<class T> struct A { A(); };

template<class T> void f(T);
template<class T> void f(T*);
template<class T> void f(const T*);

template<class T> void g(T);
template<class T> void g(T&);

template<class T> void h(const T&);
template<class T> void h(A<T>&);

void m() {
  const int *p;
  f(p);             // f(const T*) is more specialized than f(T) or f(T*)
  float x;
  g(x);             // Ambiguous: g(T) or g(T&)
  A<int> z;
  h(z);             // overload resolution selects h(A<T>&)
  const A<int> z2;
  h(z2);            // h(const T&) is called because h(A<T>&) is not callable
}

 — end example ]

Note: Since partial ordering in a call context considers only parameters for which there are explicit call arguments, some parameters are ignored (namely, function parameter packs, parameters with default arguments, and ellipsis parameters). [ Example:

template<class T> void f(T);            // #1
template<class T> void f(T*, int=1);    // #2
template<class T> void g(T);            // #3
template<class T> void g(T*, ...);      // #4

int main() {
  int* ip;
  f(ip);            // calls #2
  g(ip);            // calls #4
}

 — end example ][ Example:

template<class T, class U> struct A { };

template<class T, class U> void f(U, A<U, T>* p = 0); // #1
template<         class U> void f(U, A<U, U>* p = 0); // #2
template<class T         > void g(T, T = T());        // #3
template<class T, class... U> void g(T, U ...);       // #4

void h() {
  f<int>(42, (A<int, int>*)0);                        // calls #2
  f<int>(42);                                         // error: ambiguous
  g(42);                                              // error: ambiguous
}

 — end example ][ Example:

template<class T, class... U> void f(T, U...);        // #1
template<class T            > void f(T);              // #2
template<class T, class... U> void g(T*, U...);       // #3
template<class T            > void g(T);              // #4

void h(int i) {
  f(&i);                                              // error: ambiguous
  g(&i);                                              // OK: calls #3
}

 — end example ] — end note ]

14.5.7 Alias templates [temp.alias]

A template-declaration in which the declaration is an alias-declaration (Clause [dcl.dcl]) declares the identifier to be a alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.

When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template. [ Note: An alias template name is never deduced. — end note ] [ Example:

template<class T> struct Alloc { /* ... */ };
template<class T> using Vec = vector<T, Alloc<T>>;
Vec<int> v;         // same as vector<int, Alloc<int>> v;

template<class T>
  void process(Vec<T>& v)
  { /* ... */ }

template<class T>
  void process(vector<T, Alloc<T>>& w)
  { /* ... */ }     // error: redefinition

template<template<class> class TT>
  void f(TT<int>);

f(v);               // error: Vec not deduced

template<template<class,class> class TT>
  void g(TT<int, Alloc<int>>);
g(v);               // OK: TT = vector

 — end example ]

The type-id in an alias template declaration shall not refer to the alias template being declared. The type produced by an alias template specialization shall not directly or indirectly make use of that specialization. [ Example:

template <class T> struct A;
template <class T> using B = typename A<T>::U;
template <class T> struct A {
  typedef B<T> U;
};
B<short> b;         // error: instantiation of B<short> uses own type via A<short>::U

 — end example ]