class A
{
};
template <typename A, int S>
class B
{
public:
static int a[S];
B()
{
a[0] = 0;
}
};
template<> int B<A, 1>::a[1];
int main()
{
B<A, 1> t;
t;
}
It compiles under GCC 4.1, but does not link:
static.cpp:(.text._ZN1BI1ALi1EEC1Ev[B<A, 1>::B()]+0x5): undefined reference to `B<A, 1>::a'
I would prefer to keep initialisation specialised if it is possible, since the array holds some data specific to the type.
For static member specializations, if you don't initialize the member, it is taken as a specialization declaration, that just says "Oh, don't instantiate the member from the primary template, because there is a specialized definition somewhere else". It should be mentioned that the definition should appear in a .cpp file (otherwise, you will earn the opposite: multiple definitions), and the declaration without initializer should still be placed in the header file.
Now the correct syntax is indeed the following, and it should not appear in a header file, but in a
.cpp
fileThe following should still appear in a header file:
This will serve as the specialization declaration.
From this, it follows that you can't specialize a member that only has a default constructor and is not copyable, because you would need this syntax:
C++0x fixes this:
For the Standardese people among us, here are the quotes:
14.7.3/6
:14.7.3/15
:3.2/3
:3.2/5
:The restriction of this to "for which some template parameters are not specified" means that we are allowed to do the following, placing it into a header (thus possibly having multiple definitions of this specialization):
In your case, you have all parameters specified, making it not being covered by the one defintion rule for allowing multiple definitions.
You need to actually assign a value to it.
It does not link because you don't define a value to your static member.
Edit:
Btw: I would always prefer to use boost::array instead of native C-types: