testcase # http://149.156.124.14/~pluto/tmp/siod.ii # gcc -v (fresh build) Reading specs from /usr/lib/gcc/pentium3-pld-linux/3.4.0/specs Configured with: ../configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-languages=c,c++,f77,objc,ada,java --enable-c99 --enable-long-long --enable-multilib --enable-nls --with-gnu-as --with-gnu-ld --with-system-zlib --with-slibdir=/lib --without-x pentium3-pld-linux Thread model: posix gcc version 3.4.0 20040416 (prerelease) (PLD Linux)
Reduced to: template<class K, class V> class EST_THash; class EST_String { }; class EST_Regex { }; template<class K, class V> class EST_THash { private: static V Dummy_Value; static K Dummy_Key; }; EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; But this is invalid. to explicit instantiation, do the follwoing: template <> EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template <> EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; template EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; But just to define the space for the definition do: template <> EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template <> EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key;
Addendum for those who continue to have difficulty: I found that the order of the "template ..." vs. "template<> ..." made a difference, but in linking, not in compiling. From the previous example: template <> EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template <> EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; template EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; The (equivalent of the) above would not generate symbols in my '.o', however: template EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; template <> EST_Regex * EST_THash< EST_String, EST_Regex * >::Dummy_Value; template <> EST_String EST_THash< EST_String, EST_Regex * >::Dummy_Key; will work. (Note: my case was slightly more complicated, in that instead of "EST_Regex" for the final type, I had a templated type). This was in 3.4.2. Hope this helps.