Using the GNU extension for forward declaration of explicit instantiations ("extern template...") seems to make static member definitions fall under the rules of declarations:
$ cat /tmp/t.cpp struct C {}; template<typename T> struct S { static T v; }; template<typename T> T S<T>::v = T(); extern template class S<C>; C c = S<C>::v; $ bin/g++ -c /tmp/t.cpp /tmp/t.cpp: In instantiation of C S<C>::v: /tmp/t.cpp:11: instantiated from here /tmp/t.cpp:7: error: S<C>::v cannot be initialized by a non-constant expression when being declared $ bin/g++ -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc/configure --prefix=/M/src/inst --enable-languages=c++ --disable-bootstrap --disable-multilib Thread model: posix gcc version 4.3.0 20070810 (experimental) Known workarounds for this issue are: 1. using g++ 3.x rather than the 4.1.3, 4.2.1 or trunk (r127350) that I tried 2. removing the "extern template" line 3. changing the order of the structure declaration, data member definition and forward declaration lines 4. providing an explicit specialization of the static data members for the forward-declared instantiations -- Summary: "extern template" GNU extension makes static data member definition a declaration Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gcc-bugzilla at waba dot be GCC build triplet: x86_64-linux-gnu GCC host triplet: x86_64-linux-gnu GCC target triplet: x86_64-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33047