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
, orconsteval
specifiers.
(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.