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?
CodePudding user response:
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.