I found out that you can specialize a template after it's first use if you use it using a wrapper template. Simple example:
#include <iostream>
template<typename T>
const char* templateImpl();
template<typename T>
const char* templateGetter() { return templateImpl<T>(); }
struct S{};
int main(){ std::cout << templateGetter<S>() << std::endl; return 0; }
template<>
const char* templateImpl<S>(){ return "S"; }
This works with every compiler - I'm not surprised MSVC compiles it since it handles templates differently, but GCC and clang allow it too. I thought the standard required the specialization to occur before the first use, which in this case would mean before main and expected them to report an error.
Did I miss something, is this code standard compliant?
To clarify, if I change templateGetter<S>
to templateImpl<S>
in main, the program won't compile with the error message I would expect from this too:
See Question&Answers more detail:osmain.cpp:14:29: error: specialization of 'const char* templateImpl() [with T = S]' after instantiation