10

次のクラスについて考えてみます。

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およびComeauC++でテストしたときに、期待どおりにコンパイルおよび機能します。ただし、を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. FooVC ++ 2010でこれを修正するにはどうすればよいですか(つまり、内部の疑似明示的な特殊化をテンプレートに保持します)?
4

1 に答える 1

4

VC ++ 2010でこれを修正するにはどうすればよいですか(つまり、テンプレート化されたFooに内部の疑似明示的な特殊化を保持します)?

非テンプレート基本クラスで宣言することにより、列挙型を非依存にすることができます(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が何らかの形で依存している場合でも、「エラークラス」リンクの例のように、特殊化のパラメータに依存しない限り、名前が不正になることはありません。

于 2010-07-18T20:19:34.593 に答える