While trying to get my thoughts straight about storage class, I wrote the following snippet:
#include <iostream>
template<typename T> T pi;
template<> extern int pi<int>;
int main() {
std::cout << pi<int> << '\n';
}
gcc gives me a compilation error explicit template specialization cannot have a storage class
that I can't relate with, for instance, cppreference storage class specifiers.
clang compiles but gives me a "undefined reference" error on link which disappear if I initialize the variable with: template<> extern int pi<int>{3};
But it gives me a warning about initializing an extern
variable (which would be, if I get it right, a plain error with a non-template variable)
msvc compiles and links without blinking an eye.
Which compiler is correct (if any) and why?
NB in real code I would have made the specialization inline constexpr
GCC's diagnostic is correct, as per [temp.expl.spec]/2:
An explicit specialization shall not use a storage-class-specifier other than
thread_local
.