ejoerns
ejoerns

Reputation: 1015

const variable as non-type template parameter (VARIABLE cannot appear in a constant-expression)

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

Answers (2)

user743382
user743382

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

sehe
sehe

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

Related Questions