If one has a template constexpr variable (e.g. for computing Fibonacci sequence) and would like to instantiate it for some template argument, must constexpr keyword be repeated during instantiation?
template<int N> constexpr size_t fib = fib<N-1> + fib<N-2>;
template<> constexpr size_t fib<1> = 1;
template<> constexpr size_t fib<2> = 1;
//template constexpr size_t fib<70>; // GCC error
template size_t fib<70>; // Clang error
The problem here is that GCC insists on removing the keyword:
error: explicit instantiation shall not use 'constexpr' specifier
while Clang insists on keeping it:
error: type 'size_t' (aka 'unsigned long') of explicit instantiation of 'fib' does not match expected type 'const size_t' (aka 'const unsigned long')
Demo: https://gcc.godbolt.org/z/f6rMjz95E
Which compiler is correct here according to the standard?
This is probably a Clang bug. From temp.explicit#3
... An explicit instantiation of a function template, member function of a class template, or variable template shall not use the
inline,constexpr, orconstevalspecifiers.
(emphasis mine)
Which is exactly what the GCC error message says.
Clang's error message says that const is missing from the explicit instantiation, and adding that
template size_t const fib<70>; // ok everywhere
does allow Clang to compile the code as well.