使用枚举声明?

yes*_*aaj 7 c++ enums using-declaration

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

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

using Sample::Colour;
Run Code Online (Sandbox Code Playgroud)

不起作用!! 我们是否需要为枚举类型的每个枚举器添加使用声明?如下

using sample::Colour::RED;
Run Code Online (Sandbox Code Playgroud)

Ste*_*cey 10

类没有定义命名空间,因此"使用"在这里不适用.

此外,您需要公开枚举.

如果您尝试在同一个类中使用枚举,这是一个示例:

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

  void foo();
}

void Sample::foo() {
  Colour foo = RED;
}
Run Code Online (Sandbox Code Playgroud)

并且无需课程即可访问它:

void bar() {
  Sample::Colour colour = Sample::RED;
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*den 8

要添加到Stevela的答案,原始代码的问题是您引用成员,但using声明本身不是成员声明:

7.3.3/6有:

类成员的使用声明应为成员声明.

要突出显示这一点,以下示例可以正常工作:

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

class Derived : public Sample
{
public:
  using Sample::Colour;  // OK
};
Run Code Online (Sandbox Code Playgroud)

最后,正如Igor Semenov 在此指出的那样,即使将枚举定义移动到命名空间中,从而允许使用声明,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
}
Run Code Online (Sandbox Code Playgroud)

相关基础类型

为了允许部分和显式特化,当编译器解析类模板时,它不会在依赖基类中执行任何查找.因此,使用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;
  }
};
Run Code Online (Sandbox Code Playgroud)

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

假定模板声明或定义中使用的名称以及依赖于模板参数的名称不会命名类型,除非适用的名称查找找到类型名称或名称由关键字typename限定.

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

  1. Lookup for 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;
  }
};
Run Code Online (Sandbox Code Playgroud)

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


Igo*_*nov 5

C++标准,7.3.3.1:

using声明中指定的成员名称在using声明出现的声明区域中声明.[注意:只声明指定的名称; 在using-declaration中指定枚举名称不会在using-declaration的声明性区域中声明其枚举数. - 尾注]

  • 你能帮我解释一下这个成语吗,我的英语不是很强?:) (2认同)
  • 我不确定标准是用英文写的.看起来很像律师说话:-) (2认同)

RL-*_*L-S 5

到目前为止,有一个相关的问题:“using enum” in C++20

\n\n

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

\n\n
enum class fruit {\n    orange,\n    apple,\n};\n\nstruct S {\n  using enum fruit;             // OK, introduces orange and apple into S\n};\nvoid f() {\n  S s;\n  s.orange;                     // OK, names fruit\xe2\x80\x8b::\xe2\x80\x8borange\n  S::orange;                    // OK, names fruit\xe2\x80\x8b::\xe2\x80\x8borange\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n