G++ Compiler Error or faulty code? : "template definition of non-template"

As part of a traits class for a larger program, I attempted to create a static class variable which could have a different value depending on the type that the enclosing class template was instantiated with.

I've simplified the relevant code to produce a bare-bones example of what I'm talking about:

#include <iostream>
#include <string>
#include <type_traits>

template <class T, class Enable = void>
struct Foo;

template <class T>
struct Foo<T,
    typename std::enable_if<std::is_integral<T>::value>::type
>
{
    static std::string message;
};

template <class T>
struct Foo<T,
    typename std::enable_if<std::is_floating_point<T>::value>::type
>
{
    static std::string message;
};

template <class T, class Enable>
std::string Foo<T, Enable>::message;

With GCC 4.6, this gives a compiler error: template definition of non-template ‘std::string Foo<T, Enable>::message. The problem occurs because of the last two lines, where I'm just defining the static variable std::string Foo<T, Enable>::message.

I'm confused why this is happening. The compiler error goes away if I omit the last two lines (but of course that causes linker errors.) Is this a compiler error with GCC?

Answers


This only works when your template parameters match the partial specialization:

template <class T>
std::string Foo<T,
    typename std::enable_if<std::is_integral<T>::value>::type
>::message;

template <class T>
std::string Foo<T,
    typename std::enable_if<std::is_floating_point<T>::value>::type
>::message;

This is specified in section 14.5.4.3 of the C++03 standard. The idea is that a partial specialization is a new template and the template parameters of members that are defined externally have to match the template parameters of the class definition so that it knows which template the member goes with.

In your example, the rule avoids defining the message member for types that are not integral or floating point.


Need Your Help

How to kill playing a wave file mid file successfully?

ios objective-c iphone

User will play a wave file by holding a key down.

When do you use dependency injection?

dependency-injection

I've been using StructureMap recently and have enjoyed the experience thoroughly. However, I can see how one can easily get carried away with interfacing everything out and end up with classes tha...