When I try to compile this with Clang
template<class T>
struct Field
{
char const *name;
Field(char const *name) : name(name) { }
};
template<class Derived>
class CRTP { static Field<Derived> const _field; };
class Class : public CRTP<Class> { };
Field<Class> const CRTP<Class>::_field("blah");
int main() { }
I get
error: template specialization requires 'template<>'
Field<Class> const CRTP<Class>::_field("blah");
~~~~~~~~~~~ ^
I don't understand the error at all. What is wrong with my definition of _field
and how do I fix it?
(Note that the arguments to _field
are not necessarily the same for all subclasses.)
The error says exactly what is missing.
template<>
is missing before that line.Note, however, that your typing of
Field<Class>
, if unique, could be used to construct all instances ofField<Class>
with a given string.which means that every instance of
Field<Class>
always has the name"blah"
.One question I would have is, do you really need storage for said
Field<Class>
to actually have a pointer to a string, and if so does it need to be unique, and if so does it need to be "bare"? Because figuring out where thestatic
instance exists is somewhat annoying.Together with
field_traits
above:this moves the problem of "where is the
_field
stored" to being the compilers problem. And it is initialized by the contents offield_traits<T>::get_name()
.A static data member must have both a declaration and a definition. If this was a plain class it would look like this:
Templates aren't ordinarily defined in source files, so the code would look something like this:
In your code, you don't have the definition of the static data member. That's okay if you don't use it. But the code that the compiler is complaining about defines a static data member for
CRTP<Class>
; that's a specialization (because it's not applicable to all instantiations ofCRTP
, just to this one), and the compiler is saying that you have to tell it that it's a specialization. So do as you're told:or, to write the non-specialized template version, use the usual template syntax:
For the compiler to identify this as a template specialization (e.g. to be able to check the syntax), you need the
template
keyword:Its brackets are empty as all template parameters are specialized, but you cannot just leave it away.