问题
struct Bar {
enum { Special = 4 };
};
template<class T, int K> struct Foo {};
template<class T> struct Foo<T,T::Special> {};
Usage:
Foo<Bar> aa;
fails to compile using gcc 4.1.2
It complains about the usage of T::Special
for partial specilization of Foo. If Special
was a class the solution would be to a typename in front of it. Is there something equivalent to it for enums (or integers)?
回答1:
Since that is not allowed by C++ as explained by Prasoon, so an alternative solution would be to use EnumToType
class template,
struct Bar {
enum { Special = 4 };
};
template<int e>
struct EnumToType
{
static const int value = e;
};
template<class T, class K> //note I changed from "int K" to "class K"
struct Foo
{};
template<class T>
struct Foo<T, EnumToType<(int)T::Special> >
{
static const int enumValue = T::Special;
};
Sample code at ideone : http://www.ideone.com/JPvZy
Or, you can simply specialize like this (if it solves your problem),
template<class T> struct Foo<T,Bar::Special> {};
//usage
Foo<Bar, Bar::Special> f;
回答2:
The type of a non-type template argument cannot depend on a template parameter of a partial specialization.
ISO C++03 14.5.4/9 says
A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; //error
template <int I, int J> struct B {};
template <int I> struct B<I, I> {}; //OK
So something like this is illegal template<class T> struct Foo<T,T::Special> {};
because T::Special
depends on T
The usage is also illegal. You have provided one template argument but you need to provide two.
来源:https://stackoverflow.com/questions/4543720/is-it-possible-to-specialize-a-template-using-a-member-enum