Подтвердить что ты не робот

Можно ли специализировать шаблон с использованием перечисления участника?

struct Bar {
  enum { Special = 4 };
};

template<class T, int K> struct Foo {};
template<class T> struct Foo<T,T::Special> {};

Использование:

Foo<Bar> aa;

не удается скомпилировать с использованием gcc 4.1.2 Он жалуется на использование T::Special для частичной спецификации Foo. Если Special был классом, решение было бы перед ним. Есть ли что-то эквивалентное ему для перечислений (или целых чисел)?

4b9b3361

Ответ 1

Поскольку это не разрешено С++ как объяснено компанией Prasoon, поэтому альтернативным решением было бы использовать шаблон класса EnumToType,

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;
};

Пример кода на ideone: http://www.ideone.com/JPvZy


Или вы можете просто так специализироваться (если он решает вашу проблему),

template<class T> struct Foo<T,Bar::Special> {};

//usage
Foo<Bar, Bar::Special> f;

Ответ 2

Тип аргумента шаблона непигового типа не может зависеть от параметра шаблона частичной специализации.

ISO С++ 03 14.5.4/9 говорит

Частично специализированное выражение непигового аргумента не должно включать параметр шаблона частичной специализации, за исключением случаев, когда выражение аргумента является простым идентификатором.

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

Итак, что-то вроде этого незаконно template<class T> struct Foo<T,T::Special> {};, потому что T::Special зависит от T

Использование также является незаконным. Вы предоставили один аргумент шаблона, но вам нужно предоставить два.