Here is the SSCCE example of my problem:
// 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: Changing LibraryT<MyEnum::Enum, MyEnumTemplate>
to LibraryT<typename MyEnum::Enum, MyEnumTemplate>
has no effect]
The functionality I desire is the ability to create a library based on an enum and a class which is specialized by that enum. Above is my first attempt. I believe it is 100% C++, and GCC backs me up and says it all works. However, I want it to compile with the MSVC++ Compiler and it refuses:
error C3201: the template parameter list for class template 'MyEnumTemplate'
does not match the template parameter list for template parameter 'EnumStruct'
Is there some way I can make the MSVC++ compiler [EDIT: MSVC++ 11 Compiler (VS 2012)] like my code? Either by some addition specifications or different approach?
Hard code the enum type to be some integral type (the underlying type). Then no problems. But then my library is operating on integrals instead of the enum type (undesirable, but working)
// 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;
}
This is a known bug in the Visual C++ compiler. See the following bug on Microsoft Connect for more information (the repro is slightly different, but the issue is effectively the same):
C++ compiler bug - cannot use template parameters inside nested template declaration
The recommended workaround is to use an integer type for the template parameter of the template template parameter, which is what you have done in your "possible (but undesirable) solution."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With