A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://timsong-cpp.github.io/cppwp/n4140/temp.arg below:

[temp.arg]

14.3 Template arguments [temp.arg]

There are three forms of template-argument, corresponding to the three forms of template-parameter: type, non-type and template. The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list. When the parameter declared by the template is a template parameter pack ([temp.variadic]), it will correspond to zero or more template-arguments. [ Example:

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

Array<int> v1(20);
typedef std::complex<double> dcomplex;                                          Array<dcomplex> v2(30);
Array<dcomplex> v3(40);

void bar() {
  v1[3] = 7;
  v2[3] = v3.elem(4) = dcomplex(7,8);
}

 — end example ]

In a template-argument, an ambiguity between a type-id and an expression is resolved to a type-id, regardless of the form of the corresponding template-parameter.139Example:

template<class T> void f();
template<int I> void f();

void g() {
  f<int()>();       }

 — end example ]

The name of a template-argument shall be accessible at the point where it is used as a template-argument. [ Note: If the name of the template-argument is accessible at the point where it is used as a template-argument, there is no further access restriction in the resulting instantiation where the corresponding template-parameter name is used.  — end note ] [ Example:

template<class T> class X {
  static T t;
};

class Y {
private:
  struct S {  };
  X<S> x;                                                   };

X<Y::S> y;          

 — end example ] For a template-argument that is a class type or a class template, the template definition has no special access rights to the members of the template-argument. [ Example:

template <template <class TT> class T> class A {
  typename T<int>::S s;
};

template <class U> class B {
private:
  struct S {  };
};

A<B> b;             

 — end example ]

When template argument packs or default template-arguments are used, a template-argument list can be empty. In that case the empty <> brackets shall still be used as the template-argument-list.Example:

template<class T = char> class String;
String<>* p;                    String* q;                      template<class ... Elements> class Tuple;
Tuple<>* t;                     Tuple* u;                       

 — end example ]

An explicit destructor call ([class.dtor]) for an object that has a type that is a class template specialization may explicitly specify the template-arguments. [ Example:

template<class T> struct A {
  ~A();
};
void f(A<int>* p, A<int>* q) {
  p->A<int>::~A();                q->A<int>::~A<int>();         }

 — end example ]

If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a template specialization, the program is ill-formed.

When the template in a template-id is an overloaded function template, both non-template functions in the overload set and function templates in the overload set for which the template-arguments do not match the template-parameters are ignored. If none of the function templates have matching template-parameters, the program is ill-formed.

14.3.1 Template type arguments [temp.arg.type]

Example:

template <class T> class X { };
template <class T> void f(T t) { }
struct { } unnamed_obj;

void f() {
  struct A { };
  enum { e1 };
  typedef struct { } B;
  B b;
  X<A> x1;            X<A*> x2;           X<B> x3;            f(e1);              f(unnamed_obj);     f(b);             }

 — end example ] [ Note: A template type argument may be an incomplete type ([basic.types]).  — end note ]

If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [ Example:

template<class T> struct A {
  static T t;
};
typedef int function();
A<function> a;                                                  

 — end example ]

14.3.2 Template non-type arguments [temp.arg.nontype]

A template-argument for a non-type, non-template template-parameter shall be one of:

Note: A string literal ([lex.string]) does not satisfy the requirements of any of these categories and thus is not an acceptable template-argument. [ Example:

template<class T, const char* p> class X {
  
};

X<int, "Studebaker"> x1;        
const char p[] = "Vivisectionist";
X<int,p> x2;                    

 — end example ]  — end note ]

Note: Addresses of array elements and names or addresses of non-static class members are not acceptable template-arguments. [ Example:

template<int* p> class X { };

int a[10];
struct S { int m; static int s; } s;

X<&a[2]> x3;                    X<&s.m> x4;                     X<&s.s> x5;                     X<&S::s> x6;                    

 — end example ]  — end note ]

Note: Temporaries, unnamed lvalues, and named lvalues with no linkage are not acceptable template-arguments when the corresponding template-parameter has reference type. [ Example:

template<const int& CRI> struct B {  };

B<1> b2;                        
int c = 1;
B<c> b1;                        

 — end example ]  — end note ]

The following conversions are performed on each expression used as a non-type template-argument. If a non-type template-argument cannot be converted to the type of the corresponding template-parameter then the program is ill-formed.

Example:

template<const int* pci> struct X {  };
int ai[10];
X<ai> xi;                       
struct Y {  };
template<const Y& b> struct Z {  };
Y y;
Z<y> z;                         
template<int (&pa)[5]> struct W {  };
int b[5];
W<b> w;                         
void f(char);
void f(int);

template<void (*pf)(int)> struct A {  };

A<&f> a;                        

 — end example ]

14.3.3 Template template arguments [temp.arg.template]

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression. When the template-argument names a class template, only primary class templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.

Any partial specializations ([temp.class.spec]) associated with the primary class template or primary variable template are considered when a specialization based on the template template-parameter is instantiated. If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed; no diagnostic is required. [ Example:

template<class T> class A {       int x;
};
template<class T> class A<T*> {   long x;
};
template<template<class U> class V> class C {
  V<int>  y;
  V<int*> z;
};
C<A> c;                                                                                                                         

 — end example ]

A template-argument matches a template template-parameter (call it P) when each of the template parameters in the template-parameter-list of the template-argument's corresponding class template or alias template (call it A) matches the corresponding template parameter in the template-parameter-list of P. Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent ([temp.over.link]), and for template template-parameters, each of their corresponding template-parameters matches, recursively. When P's template-parameter-list contains a template parameter pack ([temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs in the template-parameter-list of A with the same type and form as the template parameter pack in P (ignoring whether those template parameters are template parameter packs).

Example:

template<class T> class A {  };
template<class T, class U = T> class B {  };
template <class ... Types> class C {  };

template<template<class> class P> class X {  };
template<template<class ...> class Q> class Y {  };

X<A> xa;            X<B> xb;            X<C> xc;            
Y<A> ya;            Y<B> yb;            Y<C> yc;            

 — end example ]

Example:

template <class T> struct eval;

template <template <class, class...> class TT, class T1, class... Rest>
struct eval<TT<T1, Rest...>> { };

template <class T1> struct A;
template <class T1, class T2> struct B;
template <int N> struct C;
template <class T1, int N> struct D;
template <class T1, class T2, int N = 17> struct E;

eval<A<int>> eA;                eval<B<int, float>> eB;         eval<C<17>> eC;                 eval<D<int, 17>> eD;            eval<E<int, float>> eE;         

 — end example ]


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4