[英]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: 您的方法失败有两个原因:
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。
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.