This is because the definition of a static data item is the template itself. Allowing this is necessary for the same reason that you are allowed to have a function template that is not embedded several times in the program. You need a template to create the resulting object (say, a function or a static data member). If you fail to establish a definition for a static data item, how would you create an instance of the following
template<typename T> struct F { static int const value; }; template<typename T> int const F<T>::value = sizeof(T);
It is not known what T means - the standard says that a definition outside the class template is a template definition in which parameters are inherited from the owner of the class template.
I did an experiment with GCC. In the following case, we have one implicit instantiation of F<float>::value and one explicit specialization F<char>::value , which must be defined in the .cpp file so as not to lead to duplicate symbol errors when included several times.
// Translation Unit 1 template<typename T> struct F { static int value; }; template<typename T> int F<T>::value = sizeof(T); // this would belong into a .cpp file template<> int F<char>::value = 2; // this implicitly instantiates F<float>::value int test = F<float>::value; int main() { }
The second translation unit contains only another implicit creation of the same static data item
template<typename T> struct F { static int value; }; template<typename T> int F<T>::value = sizeof(T); int test1 = F<float>::value;
Here's what we get with GCC - it makes every implicit creation in weak characters and inserts it into its section. Weak characters will not cause errors if there are several during connection. Instead, the linker selects one instance and discards the others, assuming that they are all the same.
objdump -Ct main1.o # => # cut down to the important ones 00000000 l df *ABS* 00000000 main1.cpp 0000000a l F .text 0000001e __static_initialization_and_destruction_0(int, int) 00000000 ld .data._ZN1FIfE5valueE 00000000 .data._ZN1FIfE5valueE 00000028 l F .text 0000001c global constructors keyed to _ZN1FIcE5valueE 00000000 g O .data 00000004 F<char>::value 00000000 g O .bss 00000004 test 00000000 g F .text 0000000a main 00000000 w O .data._ZN1FIfE5valueE 00000004 F<float>::value
Thus, as we can see, F<float>::value is a weak character, which means that the linker can see several of them during communication. test , main and F<char>::value are global (not weak) characters. By linking main1.o and main2.o together, we see on the output of the map ( -Wl,-M ) the following
# (mangled name) .data._ZN1FIfE5valueE 0x080497ac 0x4 main1.o 0x080497ac F<float>::value
This means that it actually deletes all but one instance.