17 Templates [temp]

17.3 Template arguments [temp.arg]

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

Если тип a template-parameter содержит a placeholder type, выводимый тип параметра определяется по типу template-argument by placeholder type deduction. Если выведенный тип параметра не разрешен для template-parameterобъявления ([temp.param]), программа имеет неправильный формат.

A template-argument для нетипа template-parameter должен быть converted constant expression типа template-parameter. Для не являющегося типом template-parameterссылки или типа указателя значение константного выражения не должно ссылаться (или для типа указателя не должно быть адресом):

[ Note: Если template-argument представляет собой набор перегруженных функций (или указатель или указатель на член), функция сопоставления выбирается из set ([over.over]). ]end note

[Example:

template<const int* pci> struct X { /* ... */ };
int ai[10];
X<ai> xi;                       // array to pointer and qualification conversions

struct Y { /* ... */ };
template<const Y& b> struct Z { /* ... */ };
Y y;
Z<y> z;                         // no conversion, but note extra cv-qualification

template<int (&pa)[5]> struct W { /* ... */ };
int b[5];
W<b> w;                         // no conversion

void f(char);
void f(int);

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

A<&f> a;                        // selects f(int)

template<auto n> struct B { /* ... */ };
B<5> b1;                        // OK: template parameter type is int
B<'a'> b2;                      // OK: template parameter type is char
B<2.5> b3;                      // error: template parameter type cannot be double

end example]

[ Note: A string literal не является приемлемым template-argument. [Example:

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

X<int, "Studebaker"> x1;        // error: string literal as template-argument

const char p[] = "Vivisectionist";
X<int,p> x2;                    // OK

end example] ]end note

[ Note: Адрес элемента массива или нестатического элемента данных недопустим template-argument. [Example:

template<int* p> class X { };

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

X<&a[2]> x3;                    // error: address of array element
X<&s.m> x4;                     // error: address of non-static member
X<&s.s> x5;                     // OK: address of static member
X<&S::s> x6;                    // OK: address of static member

end example] ]end note

[ Note: Временный объект неприемлем, template-argument если соответствующий template-parameter имеет ссылочный тип. [Example:

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

B<1> b2;                        // error: temporary would be required for template argument

int c = 1;
B<c> b1;                        // OK

end example] ]end note