Reputation: 1015
Why does this work?
char __nontype[] = "foo";
typedef TemplateClass<T, __nontype> MyClass;
But this (with a constant variable) not?
const char __nontype[] = "foo";
typedef TemplateClass<T, __nontype> MyClass;
Compiler Error:
error: ‘__nontype’ cannot appear in a constant-expression
error: template argument 2 is invalid
Upvotes: 8
Views: 2551
Reputation:
The difference is because const
affects the linkage. It works if you add extern
. That said, as far as I can tell:
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:
- an integral constant expression (including a constant expression of literal class type that can be used as an integral constant expression as described in 5.19); or
- the name of a non-type template-parameter; or
- a constant expression (5.19) 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 (4.10); or
- a constant expression that evaluates to a null member pointer value (4.11); or
- a pointer to member expressed as described in 5.3.1.
it should also work without extern
. The object is allowed to have internal linkage, but your compiler does not yet support that. This is one of the changes in C++11, the previous C++ standard did not allow it.
Upvotes: 6
Reputation: 392853
The error says it: the result is not a constant expression (it is known at link time, but not compile time).
Here is an example that would work:
typedef const char *nontype_t;
template <nontype_t> struct Y {};
char hello[] = "hello";
constexpr char* world = hello;
int main()
{
Y<hello> a;
}
Upvotes: 1