c++language-lawyerconstexprexplicit-instantiation

How to make explicit instantiation of template constexpr variable in C++?


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?


Solution

  • 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, or consteval 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.