Можно ли специализировать шаблон, используя перечисление членов? - PullRequest
20 голосов
/ 28 декабря 2010
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 был классом, решением было бы имя типа перед ним. Есть ли что-то эквивалентное этому для перечислений (или целых чисел)?

Ответы [ 2 ]

16 голосов
/ 28 декабря 2010

Поскольку это не разрешено в C ++, как объяснил в 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;
9 голосов
/ 28 декабря 2010

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

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

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

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

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

...