[temp.arg.general]

# 13 Templates [[temp]](./#temp)

## 13.4 Template arguments [[temp.arg]](temp.arg#general)

### 13.4.1 General [temp.arg.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1009)

The type and form of each [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") specified
in a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or
in a [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") shall match the type and form specified for the corresponding
parameter declared by the template in its[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")[.](#1.sentence-1)

When the parameter declared by the template is a[template parameter pack](temp.variadic#def:template_parameter_pack "13.7.4 Variadic templates [temp.variadic]"), it will correspond to zero or more[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*[.](#1.sentence-2)

[*Example [1](#example-1)*: 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; // std​::​complex is a standard library template Array<dcomplex> v2(30);
Array<dcomplex> v3(40);

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

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1043)

The template argument list of a [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") is
a template argument list in which the nth template argument
has the value of
the nth template parameter of the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")[.](#2.sentence-1)

If the nth template parameter is
a template parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")),
the nth template argument is a pack expansion
whose pattern is the name of the template parameter pack[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1053)

In a[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]"),
an ambiguity between a[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") and an expression is resolved to a[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"),
regardless of the form of the corresponding[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#3.sentence-1)[109](#footnote-109 "There is no such ambiguity in a default template-argument because the form of the template-parameter determines the allowable forms of the template-argument.")

[*Example [2](#example-2)*: template<class T> void f();template<int I> void f();

void g() { f<int()>(); // int() is a type-id: call the first f()} â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1081)

[*Note [1](#note-1)*:

Names used in a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") are subject to access control where they appear[.](#4.sentence-1)

Because a template parameter is not a class member,
no access control applies where the template parameter is used[.](#4.sentence-2)

â *end note*]

[*Example [3](#example-3)*: template<class T> class X {static T t;};

class Y {private:struct S { /* ... */ };
 X<S> x; // OK, S is accessible// X<Y​::​S> has a static member of type Y​::​S// OK, even though Y​::​S is private};

X<Y::S> y; // error: S not accessible â *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[.](#4.sentence-3)

[*Example [4](#example-4)*: template <template <class TT> class T> class A {typename T<int>::S s;};

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

A<B> b; // error: A has no access to B​::​S â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1123)

When template argument packs or default template arguments are used,
a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") list can be empty[.](#5.sentence-1)

In that case the empty<> brackets shall still be used as the[*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]")[.](#5.sentence-2)

[*Example [5](#example-5)*: template<class T = char> class String;
String<>* p; // OK, String<char> String* q; // syntax errortemplate<class ... Elements> class Tuple;
Tuple<>* t; // OK, Elements is empty Tuple* u; // syntax error â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1141)

An explicit destructor call ([[class.dtor]](class.dtor "11.4.7 Destructors")) for an object that has a type
that is a class template specialization may explicitly specify the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*[.](#6.sentence-1)

[*Example [6](#example-6)*: template<class T> struct A {~A();};void f(A<int>* p, A<int>* q) { p->A<int>::~A(); // OK, destructor call q->A<int>::~A<int>(); // OK, destructor call} â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1157)

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[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1162)

When name lookup for the component name of a[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") finds an overload set, both non-template functions in the overload
set and function templates in the overload set for
which the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* do not match the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* are ignored[.](#8.sentence-1)

[*Note [2](#note-2)*:

If none of the function templates have matching[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s*,
the program is ill-formed[.](#8.sentence-2)

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1178)

When a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") does not designate a function,
a default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is[implicitly instantiated](temp.inst "13.9.2 Implicit instantiation [temp.inst]") when the value of that default argument is needed[.](#9.sentence-1)

[*Example [7](#example-7)*: template<typename T, typename U = int> struct S { };
S<bool>* p; // the type of p is S<bool, int>*

The default argument for U is instantiated to form the type S<bool, int>*[.](#9.sentence-2)

â *end example*]

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1193)

A [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") followed by an ellipsis is
a [pack expansion](temp.variadic#def:pack_expansion "13.7.4 Variadic templates [temp.variadic]")[.](#10.sentence-1)

[109)](#footnote-109)[109)](#footnoteref-109)

There is no such ambiguity in a default[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") because the form of the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") determines the allowable forms of the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#footnote-109.sentence-1)
