(Note: I know how it is illegal, I'm looking for the reason that the language make it so.)
template<class c> void Foo(); // Note: no generic version, here or anywhere.
int main(){
Foo<int>();
return 0;
}
template<> void Foo<int>();
Error:
error: explicit specialization of 'Foo<int>' after instantiation
A quick pass with Google found this citation of the spec but that offers only the what and not the why.
Edit:
Several responses have forwarded the argument (e.g. confirmed my speculation) that the rule is this way because to do otherwise would violate the One Definition Rule (ODR). However, this is a very weak argument because it doesn't hold, in this case, for two reaons:
- Moving the explicit specialization to another translation unit solves the problem and doesn't seem to violate the ODR (or so the linker says).
- The short form of the ODR (as applied to functions) is that you can't have more than one body for any given function, and I don't. The only place the body of the function is ever defined is in the explicit specialization, so the call to
Foo<int>
can't define a generic specialization of the template because there is no generic body to be specialized.
Speculation on the matter:
A guess as to why the rule exist at all: if the first line offered a definition (as opposed to a declaration), an explicit specialization after an instantiation would be a problem because you would get multiple definitions. But in this case, the only definition in sight is the explicit specialization.
Oddly the following (or something like it in the real code I'm working on) works:
File A:
template<class c> void Foo();
int main(){
Foo<int>();
return 0;
}
File B:
template<class c> void Foo();
template<> void Foo<int>();
But to use that in general starts to create a spaghetti imports structure.
But you do have multiple definitions. You have already defined Foo< int > when you instantiate it and after that you try to specialize the template function for int, which is already defined.