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 和 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 上解决这个问题(即,在模板中保留内部伪显式专业化)?
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 回答