关于c ++:依赖的非类型模板参数

Dependent Non-Type Template Parameters

考虑以下类别:

1
2
3
4
5
6
7
8
9
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下会中断。

例如,以下代码段:

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

产生以下错误类:

1
2
3
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
  • 有人可以用简单的英语解释这里发生了什么吗?
  • 如何在VC ++ 2010上解决此问题(即在模板Foo中保留内部伪显式专业化)?

  • How can I fix this (i.e., keep internal pseudo-explicit specializations in a templated Foo) on VC++ 2010?

    您可以通过在非模板基类中声明枚举类型来使其不依赖(C ++ 03使嵌套类在#108中具有依赖性,但这不包括枚举,但是即使这样的代码仍然合法) 。

    1
    2
    3
    4
    5
    6
    7
    8
    struct FooBase {
      enum Flags {Bar, Baz, Bax};
    };

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

    "错误类别"链接已经给出了应引起错误的预期情况的描述。 该错误认为禁止所有依赖类型,但是实际上这就是标准所说的内容:

    The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization.

    因此,即使名称Flags会以某种方式依赖,只要它不依赖于"错误类"链接示例中的专业化参数,也不会使其格式错误。