使用枚举声明?

时间:2009-01-13 07:16:46

标签: c++ enums using-declaration

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

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

using Sample::Colour;

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

using sample::Colour::RED;

4 个答案:

答案 0 :(得分:10)

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

另外,你需要公开枚举。

如果你试图在同一个班级中使用枚举,这里有一个例子:

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

  void foo();
}

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

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

void bar() {
  Sample::Colour colour = Sample::RED;
}

答案 1 :(得分:8)

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

7.3.3 / 6有:

  

类成员的使用声明   应是会员声明。

要突出显示此内容,以下示例可以正常工作:

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

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

最后,正如Igor Semenov here指出的那样,即使将枚举定义移动到命名空间中,从而允许使用声明,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
  3. 限定

    因此,该示例需要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;
      }
    };
    

    注意:该标准的'98版本不允许typename与using声明一起使用,因此无法进行上述修复。请参阅Accessing types from dependent base classesCWG11

答案 2 :(得分:5)

C ++标准,7.3.3.1:

  

a中指定的成员名称   using声明在声明中声明   声明区域中的   出现使用声明。 [ 注意:   只有指定的名称才是这样   声明;指定枚举   使用声明中的名称不会   在...中声明其枚举器   using-declaration的声明   区域。 - 后注]

答案 3 :(得分:0)

现在,有一个相关的问题:'using enum' in 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内部,您也可以简单地使用orangeapple而不是fruit::orangefruit::apple。 / p>