10

using声明似乎不适用于枚举类型:

class Sample{
    public:
        enum Colour {RED, BLUE, GREEN};
}

using Sample::Colour;

不工作!

我们是否需要为每个枚举类型的枚举器添加一个using声明?如下所示:

using sample::Colour::RED;
4

4 回答 4

10

一个类没有定义命名空间,因此“使用”在这里不适用。

此外,您需要公开枚举。

如果你想在同一个类中使用枚举,这里有一个例子:

class Sample {
 public:
  enum Colour { RED, BLUE, GREEN };

  void foo();
}

void Sample::foo() {
  Colour foo = RED;
}

并从课堂外访问它:

void bar() {
  Sample::Colour colour = Sample::RED;
}
于 2009-01-13T07:27:07.327 回答
9

添加到史蒂夫·莱西的回答中,原始代码的问题是您引用了一个成员,但using声明本身并不是成员声明:

7.3.3/6 有:

一个类成员的使用声明应该是一个成员声明。

为了强调这一点,以下示例确实有效:

class Sample
{
public:
  enum Colour { RED,BLUE,GREEN};
};

class Derived : public Sample
{
public:
  using Sample::Colour;  // OK
};

最后,正如Igor Semenov 所指出的,即使将枚举定义移到命名空间中,从而允许using声明,using声明也只会将枚举类型的名称声明到命名空间中(2003 年标准参考是 7.3.3 /2)。

namespace Sample
{
  enum Colour { RED,BLUE,GREEN};
}

using Sample::Colour;
using Sample::BLUE;


void foo ()
{
  int j = BLUE; // OK
  int i = RED;  // ERROR
}

依赖基类型

当编译器解析类模板时,允许部分和显式特化。它不会在相关基类中执行任何查找。因此,以下以 Sample 作为模板的变体无法编译:

template <typename T>
class Sample
{
public:
  enum Colour { RED,BLUE,GREEN};
};

template <typename T>
class Derived : public Sample<T>
{
public:
  using Sample<T>::Colour;  // What kind of entity is Colour?

  Colour foo ()     // Not OK!
  {
  return this->RED;
  }
};

问题是Derived::Colour编译器(14.6/2)将其视为对象:

在模板声明或定义中使用并且依赖于模板参数的名称被假定为不命名类型,除非适用的名称查找找到类型名称或该名称由关键字 typename 限定。

查看名称为类型的两个条件:

  1. 查找Colour未找到类型,因为Sample<T>未搜索依赖基。
  2. 名称不符合typename

因此,该示例需要typename关键字:

template <typename T>
class Derived : public Sample<T>
{
public:
  using typename Sample<T>::Colour;  // Colour is treated as a typedef-name

  Colour foo ()  // OK
  {
  return this->RED;
  }
};

注意: 标准的 1998 版本不允许typename与 using 声明一起使用,因此无法进行上述修复。请参阅从依赖基类CWG11访问类型。

于 2009-01-13T11:43:05.143 回答
5

C++ 标准,7.3.3.1:

在 using-declaration 中指定的成员名称在 using-declaration 出现的声明区域中声明。[注:只有指定的名称是这样声明的;在 using-declaration 中指定枚举名称不会在 using-declaration 的声明区域中声明其枚举数。——尾注]

于 2009-01-13T07:28:42.847 回答
3

到目前为止,有一个相关的问题:在 C++20 中使用枚举

看起来 C++20 可以选择进行using enum声明,从而最终允许直接访问枚举类的成员,如下所示(source):

enum class fruit {
    orange,
    apple,
};

struct S {
  using enum fruit;             // OK, introduces orange and apple into S
};
void f() {
  S s;
  s.orange;                     // OK, names fruit​::​orange
  S::orange;                    // OK, names fruit​::​orange
}

当然,这意味着在内部S,您也可以简单地使用orangeandapple代替fruit::orangeand fruit::apple

于 2019-10-04T09:57:16.403 回答