Here's the minimal example of the question:
I have 3 source files:
// A.h
template<class T> int var = 2;
// A1.cpp
template<> int var<int> = 3;
template int var<int>;
// A2.cpp
template<> int var<double> = 4;
template int var<double>;
But the linker reported 2 errors saying that var<double>
and var<int>
symbols are already defined. After commenting out either template<> int var<double> = 4;
template<> int var<int> = 3;
or the lines below them, the linking process terminated normally. I opened the generated lib file with IDA, and found the 2 variables are right inside.
I used to think that template<> int var<double>
is some kind of template specilization without instantiation while template int var<double>
is instantiation of the template. But now it seems they are the same, i.e. the specialization seems to cause instantiation. Am I wrong?
[temp.expl.spec]/7 If a template ... is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
In your case, if some translation unit includes A.h
and then refers to var<int>
or var<double>
, your program is ill-formed (no diagnostic required) under this clause.
It's a good thing that you actually get an error.