Question on CRTP static member initialization with GCC
I'm trying to use CRTP for static inheritance, like so:
parent.h:
template<typename Derived>
class Parent {
static int s_number;
};
child.h:
class Child : Parent<Child> {
};
When I try to use Child::s_number I get a "Symbol not found" runtime error.=
It seems that since template instantiation is lazy I need to force it to i=
nitialize with:
(solution 1)
child.cpp:
template<>
int Child::Parent<Child>::s_number = 0;
However I have many child classes and it is a pain to initialize that every=
where, so I tried the solution in this post:
http://stackoverflow.com/questions/24725152/force-explicit-template-instant=
iation-with-crtp
Namely by doing:
(solution 2)
template <typename T, T>
struct NonTypeParameter {};
typedef NonTypeParameter<int&, s_number> dummy;
After additional testing I've found that if I use only solution 1 then I wo=
n't get any crashes when compiling with GCC 4.7.3 on my Linux Ubuntu machin=
e, but it does crash using GCC 4.7.3 on my Mac. Using only solution 2 it wi=
ll work on my Mac, but crash on my Linux machine. Using both solutions it c=
ompiles successfully and doesn't crash anywhere.
Has anyone encountered this problem before, and/or knows a portable way of =
making sure CRTP static members are initialized properly?
If it helps here is the gcc on my Mac:
$ echo $CXX
/usr/local/bin/g++-4.7
$ /usr/local/bin/g++-4.7 -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/g++-4.7
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc47/4.7.3/libexec/gcc/x86_64-appl=
e-darwin13.3.0/4.7.3/lto-wrapper
Target: x86_64-apple-darwin13.3.0
Configured with: ../configure --build=x86_64-apple-darwin13.3.0 --prefix=
=/usr/local/Cellar/gcc47/4.7.3 --enable-languages=c,c++,objc,obj-c++ --=
program-suffix=-4.7 --with-gmp=/usr/local/opt/gmp4 --with-mpfr=/usr/l=
ocal/opt/mpfr2 --with-mpc=/usr/local/opt/libmpc08 --with-ppl=/usr/local=
/opt/ppl011 --with-cloog=/usr/local/opt/cloog-ppl015 --with-system-zlib -=
-enable-version-specific-runtime-libs --enable-libstdcxx-time=yes --enabl=
e-stage1-checking --enable-checking=release --enable-lto --disable-werror=
--with-pkgversion='Homebrew gcc47 4.7.3' --with-bugurl=https://github.=
com/Homebrew/homebrew-versions/issues --enable-plugin --disable-nls --enabl=
e-multilib
Thread model: posix
gcc version 4.7.3 (Homebrew gcc47 4.7.3)
And on my Linux Ubuntu machine:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7=
..3-2ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bug=
s --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --prog=
ram-suffix=-4.7 --enable-shared --enable-linker-build-id --libexecdir=/=
usr/lib --without-included-gettext --enable-threads=posix --with-gxx-incl=
ude-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysr=
oot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-=
time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --=
enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --=
with-abi=m64 --with-multilib-list=m32,m64 --with-tune=generic --enabl=
e-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu -=
-target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04)