2012-10-04 33 views
10

Đây là SSCCE ví dụ về vấn đề của tôi:Template lớp mẫu với đặc điểm kỹ thuật enum không thành công trên 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: Thay đổi LibraryT<MyEnum::Enum, MyEnumTemplate>-LibraryT<typename MyEnum::Enum, MyEnumTemplate> không có tác dụng]

Lỗi

Chức năng tôi mong muốn là khả năng tạo ra một thư viện dựa trên một enum và một lớp được chuyên môn hóa bởi enum đó. Trên đây là nỗ lực đầu tiên của tôi. Tôi tin rằng nó là 100% C++, và GCC ủng hộ tôi và nói rằng tất cả đều hoạt động. Tuy nhiên, tôi muốn nó biên dịch với MSVC++ Compiler và nó từ chối:

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

Câu hỏi

Có một số cách tôi có thể làm cho ++ biên dịch MSVC [EDIT: MSVC++ 11 Compiler (VS 2012)] giống như mã của tôi? Hoặc là bởi một số thông số kỹ thuật bổ sung hoặc cách tiếp cận khác nhau?

Giải pháp có thể (nhưng không mong muốn)

Mã loại enum là loại không thể tách rời (loại cơ bản). Thế thì không có vấn đề gì. Nhưng sau đó thư viện của tôi đang hoạt động trên tích thay vì kiểu enum (không mong muốn, nhưng làm việc)

// 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

Trong trường hợp kết thúc là thích hợp, VC++ 2010 hoặc 2012? – ildjarn

+0

@idjarn Phần gần đây nhất: Trình biên dịch MSVC++ 11 (được bao gồm trong VS 2012) –

+0

@ahenderson Tôi tin rằng trong trường hợp này phần 'typename' là tùy chọn, thêm nó không tạo sự khác biệt –

Trả lời

3

Đây là một lỗi được biết đến trong Visual C++. Xem các lỗi sau đây trên Microsoft Connect để biết thêm thông tin (các repro là hơi khác nhau, nhưng vấn đề là có hiệu quả tương tự):

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

Cách giải quyết đề nghị là sử dụng một loại nguyên cho tham số mẫu của tham số mẫu mẫu, đó là những gì bạn đã làm trong "giải pháp có thể (nhưng không mong muốn)" của bạn.

Các vấn đề liên quan