Здесь SSCCE пример моей проблемы:
// 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;
}
[РЕДАКТИРОВАТЬ: Изменение LibraryT<MyEnum::Enum, MyEnumTemplate>
в LibraryT<typename MyEnum::Enum, MyEnumTemplate>
не имеет никакого эффекта]
Функциональность, которую я желаю, — это возможность создавать библиотеку на основе перечисления и класса, специализирующегося на этом перечислении. Выше моя первая попытка. Я считаю, что это 100% C ++, и GCC поддерживает меня и говорит, что все работает. Однако я хочу, чтобы он компилировался с компилятором MSVC ++, и он отказывается:
error C3201: the template parameter list for class template 'MyEnumTemplate'
does not match the template parameter list for template parameter 'EnumStruct'
Есть ли способ сделать компилятор MSVC ++ [РЕДАКТИРОВАТЬ: MSVC ++ 11 Compiler (VS 2012)] как мой код? Или какими-то дополнительными спецификациями или другим подходом?
Жесткий код типа enum должен быть целым типом (базовый тип). Тогда никаких проблем. Но тогда моя библиотека работает с интегралами вместо типа enum (нежелательно, но работает)
// 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;
}
Это известная ошибка в компиляторе Visual C ++. См. Следующую ошибку в Microsoft Connect для получения дополнительной информации (репродукция немного отличается, но проблема фактически та же):
Рекомендуемое обходное решение — использовать целочисленный тип для параметра шаблона параметра шаблона, что вы и сделали в своем «возможном (но нежелательном) решении».
Других решений пока нет …