template partial specialization of static fields initialisation
-
25-09-2019 - |
Question
I'm attempting something like the following:
struct MyType { };
template <typename T>
struct Test
{
static const MyType * const sm_object;
};
template <>
struct Test<void>
{
static const MyType * const sm_object;
};
template <typename T> const MyType * const Test<T>::sm_object = new MyType();
template <> const MyType * const Test<void>::sm_object = new MyType();
I include this in 2 files - a.cpp and b.cpp. I attempt to compile and get:
error C2998: 'const MyType *Test<void>::sm_object' : cannot be a template definition
I assume my C++ syntax is bad, but I can't think what I'm doing wrong.
I can't remove the template<>
from the variable definition, as I need this in multiple translation units, and that would result in a link error.
I could put the field into a base class and use the CRTP to create a new instance per type, and then the specialization wouldn't get in the way, but why doesn't this 'direct' field initialisation work? I must be missing some piece of syntax.
I'm using VS2003 :(
Solution
Judging from g++ I think you need to remove the template<>
from that line and put the remainder in just one source file (not in the header). Since it's a specialization it's just like a normal non-template static which you don't define in a header.
In some .C
file:
const MyType * const Test<void>::sm_object = new MyType();
OTHER TIPS
I believe that you want to do something like this
struct MyType { };
template <typename T>
struct Test
{
static const MyType * const sm_object;
static const MyType* set_object()
{
return nullptr;
}
};
template <>
struct Test<void>
{
static const MyType * const sm_object;
static const MyType* set_object()
{
return new MyType();
}
};
template <typename T>
const MyType * Test<T>::sm_object = Test< T >::set_object();
I believe the following code could be of quite some interest for some people:
#include <stdio.h>
template<class X,int Y>
struct B
{
X content;
static const int nr=Y;
};
int main(int, char**)
{
B<char,1> a;
B<int,2> b;
B<int,3> c;
printf("%d, %d, %d\n",a.nr,b.nr,c.nr);
}