A template-argument for a non-type, non-template template-parameter shall be one of:
for a non-type template-parameter of integral or enumeration type, a converted constant expression ([expr.const]) of the type of the template-parameter; or
the name of a non-type template-parameter; or
a constant expression ([expr.const]) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or
a constant expression that evaluates to a null pointer value ([conv.ptr]); or
a constant expression that evaluates to a null member pointer value ([conv.mem]); or
a pointer to member expressed as described in [expr.unary.op].
[ 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; // error: string literal as template-argument const char p[] = "Vivisectionist"; X<int,p> x2; // OK
— 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; // error: address of array element X<&s.m> x4; // error: address of non-static member X<&s.s> x5; // error: &S::s must be used X<&S::s> x6; // OK: address of static member
— 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; // error: temporary would be required for template argument int c = 1; B<c> b1; // OK
— 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.
For a non-type template-parameter of integral or enumeration type, conversions permitted in a converted constant expression ([expr.const]) are applied.
for a non-type template-parameter of type pointer to object, qualification conversions ([conv.qual]) and the array-to-pointer conversion ([conv.array]) are applied; if the template-argument is of type std::nullptr_t, the null pointer conversion ([conv.ptr]) is applied. [ Note: In particular, neither the null pointer conversion for a zero-valued integral constant expression ([conv.ptr]) nor the derived-to-base conversion ([conv.ptr]) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. However, both (int*)0 and nullptr are valid template-arguments for a non-type template-parameter of type “pointer to int.” — end note ]
For a non-type template-parameter of type reference to object, no conversions apply. The type referred to by the reference may be more cv-qualified than the (otherwise identical) type of the template-argument. The template-parameter is bound directly to the template-argument, which shall be an lvalue.
For a non-type template-parameter of type pointer to function, the function-to-pointer conversion ([conv.func]) is applied; if the template-argument is of type std::nullptr_t, the null pointer conversion ([conv.ptr]) is applied. If the template-argument represents a set of overloaded functions (or a pointer to such), the matching function is selected from the set ([over.over]).
For a non-type template-parameter of type reference to function, no conversions apply. If the template-argument represents a set of overloaded functions, the matching function is selected from the set ([over.over]).
For a non-type template-parameter of type pointer to member function, if the template-argument is of type std::nullptr_t, the null member pointer conversion ([conv.mem]) is applied; otherwise, no conversions apply. If the template-argument represents a set of overloaded member functions, the matching member function is selected from the set ([over.over]).
For a non-type template-parameter of type pointer to data member, qualification conversions ([conv.qual]) are applied; if the template-argument is of type std::nullptr_t, the null member pointer conversion ([conv.mem]) is applied.
[ 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)
— end example ]