简体   繁体   English

如何在C ++ 11中使用弱枚举?

[英]How to do `using` of weak enums in C++11?

I have enum definition inside a class in the header: 我在标题中的类中有枚举:

namespace A {

class B {
 public:
  enum Value {
    VALUE1 = 1,
    VALUE2 = 2,
  };
};

}

And I want to use its values in a source file without prefix, like this: 我想在没有前缀的源文件中使用它的值,如下所示:

#include "header"

int main() {
  someFn(VALUE1);

  return 0;
}

I have tried to using A::B::Value; 我试过using A::B::Value; but clang gives an error: 但是clang给出了一个错误:

using declaration can not refer to class member 使用声明不能引用类成员


Even if I move enum outside of a class: 即使我在课堂外移动枚举:

namespace A {

enum Value {
  VALUE1 = 1,
  VALUE2 = 2,
};    

}

and do using A::Value; using A::Value; , the error is gone, but the compiler complains about VALUE1 : ,错误消失了,但编译器抱怨VALUE1

use of undeclared identifier 'VALUE1' 使用未声明的标识符'VALUE1'

Is there way to use values of enum without any prefixes, if the enum is defined somewhere else? 如果枚举是在其他地方定义的,有没有办法使用没有任何前缀的枚举值? - Using #define s is out of question. - 使用#define s是#define的。

If there is no way, then what is a possible issue about implementing such behavior in C++ Standard? 如果没有办法,那么在C ++ Standard中实现这种行为可能会出现什么问题呢?

To put is simply : it is not possible, because enum is defined in the class. 简单来说就是:它是不可能的,因为枚举是在类中定义的。

If you change the class B into namespace B : 如果将class B更改为namespace B

namespace A {

namespace B {
  enum Value {
    VALUE1 = 1,
    VALUE2 = 2,
  };
};

}

then it would be possible to do (as you wrote in your code): 然后就可以了(就像你在代码中写的那样):

using A::B::Value

There are two reasons why your approaches fail: 您的方法失败有两个原因:

  1. The first reason has been described by BЈовић: You cannot introduce the name of a nested type in a namespace scope, see [namespace.udecl]/8. 第一个原因已由BЈови描述:您不能在命名空间范围中引入嵌套类型的名称,请参阅[namespace.udecl] / 8。

  2. When you write using A::B::Value; using A::B::Value;编写时using A::B::Value; , only the name of the enum itself will be introduced in the current scope, not the name of all enumerators. ,只有enum本身的名称将在当前范围内引入, 而不是所有枚举器的名称。 This allows things like: 这允许这样的事情:

     namespace Values { enum Value{ VALUE1, VALUE2 }; } using Values::Value; // don't pollute my scope with the enumerators Value v = Values::VALUE1; 

The second issue can be solved by introducing the enumerators individually: 第二个问题可以通过单独介绍枚举器来解决:

namespace A
{
    namespace B
    {
        enum Value
        {
              VALUE1
            , VALUE2
        };
    }
}

int main()
{
    using A::B::Value;
    using A::B::VALUE1;
    using A::B::VALUE2;

    Value v = VALUE1;
    v = VALUE2;
}

Alternatively, as hvd suggested in a comment , you can use a using-directive to introduce all names of a namespace: 或者,正如hvd 在注释中建议的那样 ,您可以使用using-directive来引入命名空间的所有名称:

namespace A
{
    namespace B
    {
        enum Value
        {
              VALUE1
            , VALUE2
        };
    }
}

int main()
{
    using namespace A::B;

    Value v = VALUE1;
    v = VALUE2;
}

Enums are treated in a manner similar to classes. 枚举的处理方式与类似。 Think of it as trying to do the following: 将其视为尝试执行以下操作:

class Value
{
public:
    static const int VALUE1 = 0;
};

using Value::VALUE1; // ERROR class-qualified name

In short: You can't make enum values visible this way with a using statement. 简而言之:您不能using语句以这种方式显示枚举值。

Well, the closest I can think of is: 嗯,我能想到的最接近的是:

namespace A {
  class B {
  public:
    enum Value { VALUE1 = 1, VALUE2 = 2 };
  };
};

const A::B::Value VALUE1 = A::B::VALUE1;

int main () {
  return VALUE1;
}

but its rather tedious and error prone and absolutely not worth it. 但它相当乏味和容易出错,绝对不值得。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM