Зависимые нетиповые параметры шаблона - PullRequest
10 голосов
/ 18 июля 2010

Рассмотрим следующий класс:

class Foo
{
  enum Flags {Bar, Baz, Bax};

  template<Flags, class = void> struct Internal;

  template<class unused> struct Internal<Bar, unused> {/* ... */};
  template<class unused> struct Internal<Baz, unused> {/* ... */};
  template<class unused> struct Internal<Bax, unused> {/* ... */};
};

Схема класса выше компилируется и функционирует, как и ожидалось, при тестировании на VC ++ 2010 и Comeau C ++. Однако когда Foo превращается в сам шаблон, приведенный выше фрагмент разбивается под VC ++ 2010.

Например, следующий фрагмент:

template<class> class Foo
{
  // Same contents as the original non-templated Foo.
};

Возвращает следующий класс ошибок :

C2754: 'Foo<<unnamed-symbol>>::Internal<Bar,unused>' : a partial specialization cannot have a dependent non-type template parameter
C2754: 'Foo<<unnamed-symbol>>::Internal<Baz,unused>' : a partial specialization cannot have a dependent non-type template parameter
C2754: 'Foo<<unnamed-symbol>>::Internal<Bax,unused>' : a partial specialization cannot have a dependent non-type template parameter

  1. Может кто-нибудь объяснить, что здесь происходит на простом английском?
  2. Как я могу это исправить (т.е. сохранить внутренние псевдо-явные специализации в шаблонной Foo) в VC ++ 2010?

1 Ответ

4 голосов
/ 19 июля 2010

Как я могу это исправить (т.е. сохранить внутренние псевдо-явные специализации в шаблонном Foo) на VC ++ 2010?

Вы можете сделать тип перечисления независимым, объявив егов не шаблонном базовом классе (C ++ 03 сделал вложенные классы зависимыми в # 108 , но это не включает перечисление, но даже если такой код все еще был бы допустимым).

struct FooBase { 
  enum Flags {Bar, Baz, Bax};
};

template<class> class Foo : public FooBase {
  template< ::FooBase::Flags, class = void > struct Internal;
  // same other stuff ...
};

Ссылка "класс ошибок" уже дает описание предполагаемых случаев, когда ошибка должна возникать.Ошибка считает, что все зависимые типы запрещены, но на самом деле это то, что сказано в Стандарте:

Тип параметра шаблона, соответствующего специализированному аргументу не-типа, не должен зависеть от параметраспециализации.

Таким образом, даже если имя Flags будет каким-то образом зависимым, это не сделает его плохо сформированным, если оно не зависит от параметра такой специализации, какв примере вашей ссылки "класс ошибок".

...