2012-04-09 14 views
10

Jako część klasy cech dla większego programu podjąłem próbę utworzenia statycznej zmiennej klasy, która może mieć inną wartość w zależności od typu, z którym utworzono instancję otaczającego szablonu.G ++ Błąd kompilatora lub wadliwy kod? : "definicja szablonu bez szablonu"

uprościłem odpowiedni kod do wytworzenia przykład goły, co mówię:

#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; 

z gcc 4.6, co daje błąd kompilatora: template definition of non-template ‘std::string Foo<T, Enable>::message. Problem pojawia się z powodu ostatnich dwóch linii, w których właśnie definiuję zmienną statyczną std::string Foo<T, Enable>::message.

Jestem zdezorientowany, dlaczego tak się dzieje. Błąd kompilatora zniknie, jeśli pominę dwie ostatnie linie (ale oczywiście spowoduje to błędy linkera). Czy jest to błąd kompilatora w GCC?

+2

+1 za "przykład z bezkształtnym kości". http://sscce.org/. –

+0

Musisz dołączyć

+0

@Vaughn, to nie jest problem tutaj, ale zaktualizowałem fragment kodu. – Channel72

Odpowiedz

10

ta działa tylko, gdy parametry template match częściową specjalizację:

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; 

ta jest określona w punkcie 14.5.4.3 standardu C++ 03. Chodzi o to, że częściowa specjalizacja jest nowym szablonem, a parametry szablonów członków, które są zdefiniowane zewnętrznie, muszą być zgodne z parametrami szablonu definicji klasy, aby wiedział on, z którym szablonem dany element się zgadza.

W twoim przykładzie reguła unika definiowania elementu komunikatu dla typów, które nie są integralne ani zmiennoprzecinkowe.

+0

Dlaczego to działa tylko w takim przypadku? – SirGuy

+0

Czy jest jakiś powód, dla którego jedna definicja nie działa tutaj? Czy jest to coś wymagane przez standard C++ lub dziwactwo w G ++? – Channel72

+0

@GuyGreer: Zgaduję, ponieważ pole statyczne _message_ nie jest zadeklarowane dla szablonu ogólnego (tylko dla niektórych specjalizacji). niemożliwe jest zdefiniowanie czegoś, co nie jest zadeklarowane. – user396672

Powiązane problemy