2012-10-04 8 views
10

Kod

Oto przykład mojego problemu SSCCE:Szablon klasy szablon ze specyfikacją enum nie na MSVC++ Compiler: C3201

// My Library, which I want to take in the user's enum and a template class which they put per-enum specialized code 
template <typename TEnum, template <TEnum> class EnumStruct> 
struct LibraryT { /* Library stuff */ }; 

// User Defined Enum and Associated Template (which gets specialized later) 
namespace MyEnum { 
    enum Enum { 
     Value1 /*, ... */ 
    }; 
}; 

template <MyEnum::Enum> 
struct MyEnumTemplate {}; 

template <> 
struct MyEnumTemplate<MyEnum::Value1> { /* specialized code here */ }; 

// Then the user wants to use the library: 
typedef LibraryT<MyEnum::Enum, MyEnumTemplate> MyLibrary; 

int main() { 
    MyLibrary library; 
} 

[EDIT: Zmiana LibraryT<MyEnum::Enum, MyEnumTemplate> do LibraryT<typename MyEnum::Enum, MyEnumTemplate> nie ma wpływu]

Błąd

Funkcjonalność, której pragnę jest umiejętnością tworzenia biblioteki opartej na enumie i klasie, która specjalizuje się w tym wyliczeniu. Powyżej jest moja pierwsza próba. Wierzę, że jest to 100% C++, a GCC wspiera mnie i mówi, że wszystko działa. Jednak chcę go skompilować z MSVC++ Compiler i odmawia:

error C3201: the template parameter list for class template 'MyEnumTemplate' 
    does not match the template parameter list for template parameter 'EnumStruct' 

Pytanie

Czy jest jakiś sposób mogę dokonać MSVC++ kompilator [EDIT: MSVC++ 11 Compiler (VS 2012)] jak mój kod? Czy to przez jakieś specyfikacje dodawania czy inne podejście?

możliwe (ale niepożądany) Rozwiązanie

Twardy kod typu enum być trochę integralną typu (typ bazowy). Wtedy żadnych problemów. Ale wtedy moja biblioteka działa na całek zamiast typu enum (niepożądany, ale działa)

// My Library, which I want to take in the user's enum and a template class which they put per-enum specialized code 
typedef unsigned long IntegralType; // **ADDED** 

template <template <IntegralType> class EnumStruct> // **CHANGED** 
struct LibraryT { /* Library stuff */ }; 

// User Defined Enum and Associated Template (which gets specialized later) 
namespace MyEnum { 
    enum Enum { 
     Value1 /*, ... */ 
    }; 
}; 

template <IntegralType> // **CHANGED** 
struct MyEnumTemplate {}; 

template <> 
struct MyEnumTemplate<MyEnum::Value1> {}; 

// Then the user wants to use the library: 
typedef LibraryT<MyEnumTemplate> MyLibrary; // **CHANGED** 

int main() { 
    MyLibrary library; 
} 
+0

W przypadku, gdy to się skończy, VC++ 2010 lub 2012? – ildjarn

+0

@idjarn Najnowszy: Kompilator MSVC++ 11 (jest zawarty w VS 2012) –

+0

@ ahenderson Wierzę, że w tym przypadku część 'typename' jest opcjonalna, ale dodanie jej nie ma znaczenia –

Odpowiedz

3

To znany błąd w Visual C++ kompilatora. Zobacz następujący błąd na Microsoft Connect, aby uzyskać więcej informacji (the repro jest nieco inna, ale problem jest faktycznie taka sama):

C++ compiler bug - cannot use template parameters inside nested template declaration

Zalecanym rozwiązaniem jest użycie typu INTEGER dla parametr szablonu parametru szablonu szablonu, który wykonałeś w swoim "możliwym (ale niepożądanym) rozwiązaniu".