【问题标题】:Why Doesn't This Using Declaration on a `template` Class's Enum Work?为什么在“模板”类的枚举上使用声明不起作用?
【发布时间】:2015-10-14 15:25:01
【问题描述】:

这样编译:

template <typename T> class Parent { public:
  enum MyEnum { RED,GREEN,BLUE };
};
class Child : public Parent<int> { public:
  using Parent<int>::MyEnum;
  int foo() { return GREEN; }
};
void tester() { Child d; d.foo(); }

这不是(在 gcc 上,这会输出 error: 'GREEN' was not declared in this scope):

template <typename T> class Parent { public:
  enum MyEnum { RED,GREEN,BLUE };
};
template <typename T> class Child : public Parent<T> { public:
  using Parent<T>::MyEnum;
  int foo() { return GREEN; }
};
void tester() { Child<int> d; d.foo(); }

我的问题:为什么?(另外,有什么解决方法的建议吗?)

【问题讨论】:

  • 两阶段名称查找。 GREEN 不是从属名称,在 Child&lt;int&gt;Parent&lt;int&gt; 实例化之前,在 foo 的定义点进行查找。要使其成为依赖名称(从而将查找推迟到实例化点),您必须编写 Child::GREENParent::GREENthis-&gt;GREEN
  • (c++11) enum class 在这里可能很有用,以避免常规枚举在封闭范围内自动公开常量的行为,这在这种情况下会引起很多混乱。 .
  • @IgorTandetnik int foo(Parent&lt;T&gt;::MyEnum e) { return e; } 之类的呢?
  • 怎么样?我不确定我是否理解这个问题。

标签: c++ enums scope


【解决方案1】:

对于第二个代码:

  1. 您需要添加 typename 关键字,因为您访问的类型 MyEnum 依赖于 T。将 using 的行更改为:

using typename Parent&lt;T&gt;::MyEnum;

  1. 然后,在 foo 方法中,您需要指定 GREEN 是枚举 MyEnum 的成员,如下所示:

int foo() { return MyEnum::GREEN; }

使用 gcc 和 C++11 对我来说编译得很好
实例here

它在第一个示例中有效,因为 using 行中的 MyEnum 不依赖于模板类型 T。您显式使用了类型为 int 的 Parent。

【讨论】:

    【解决方案2】:

    线

    using Parent<int>::MyEnum;
    

    与能否在行中使用GREEN 无关

    int foo() { return GREEN; }
    

    您可以删除第一行,第二行应该继续工作。

    至于第二个例子,你可以使用:

    template <typename T> class Child : public Parent<T>
    {
        public:
          using Parent<T>::GREEN;
          int foo() { return GREEN; }
    };
    

    我并不清楚为什么Parent&lt;T&gt;::GREENChild 中不自动可用

    【讨论】:

    • It's not immediately clear to me why Parent&lt;T&gt;::GREEN is not automatically available in Child 就像我说的,two-phase name lookup
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 2014-04-22
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多