user3882729
user3882729

Reputation: 1534

using const variables as non type template arguments

I have a question on using a const variable as a template argument.

The following compiles fine using gcc and clang x64 trunk:

template <int N>
void func() { }

int main(int argc, char *argv[]) { 
    const int x = 12;
    func<x>();
}

However, and as one might expect, this version of main() does not compile:

int main(int argc, char *argv[]) { 
    const int x = argc;
    func<x>();
}

Shouldn't x be required to be constexpr? Or, is const implicitly constexpr when the value can be determined at compile time?

Upvotes: 0

Views: 53

Answers (1)

user17732522
user17732522

Reputation: 76688

Normally, a variable has to be marked constexpr if you want to use its value in a constant expression (meaning, in compile-time evaluation), as is required by a template argument.

However, there is an exception for const integral and enumeration types, which are also allowed to be used in that way, assuming that they themselves are initialized with a constant expression.

In your first example, x is initialized with a constant expression. In your second example, it clearly isn't (because argc is a function parameter).

This exception has historical reasons. It was already possible to use const integral/enumeration variables in this way before constexpr was invented (which first appearing in C++11). Without such a rule, there wouldn't have been any way to provide named non-type template arguments or array bounds before C++11, other than by a preprocessor macro (as is the case for C without VLAs). And, because old code shouldn't break needlessly with new C++ versions, this exception is still in place.

Upvotes: 5

Related Questions