使用同名的类和枚举?
我有一个具有相同名称的类和枚举值。在类中我想使用给出错误的枚举。有没有什么方法可以使用枚举而无需重命名或移动到不同的名称空间?
例子:
namespace foo {
enum bar {
BAD
};
class BAD {
void worse () {
bar b = BAD; // error
}
};
};
I've a class and an enum value which have the same name. Inside the class I want to use the enum which gives an error. Is there any way to use the enum without renaming or moving to a different namespace?
Example:
namespace foo {
enum bar {
BAD
};
class BAD {
void worse () {
bar b = BAD; // error
}
};
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是执行名称查找的棘手部分之一。
C++ 中有两种标识符作用域,一种用于类类型,一种用于通用标识符作用域。枚举值 BAD 驻留在通用标识符范围内,而类类型 BAR 驻留在类标识符范围内。这就是为什么允许您同时拥有一个枚举值和一个具有相同名称的类的原因:两个名称不会冲突。
在类 BAD 中,标识符查找规则将在找到枚举之前先找到类 BAD,从而导致错误。现在,如果您完全限定标识符,则名称查找将首先检查全局标识符范围并匹配枚举值。另一方面,您必须添加 struct 或 class 关键字来声明 BAD 类型的变量。
现在,我建议反对这种用法。重复使用这样的标识符通常不是一个好主意。代码会更加复杂,并且可能会误导普通读者(相同的非限定标识符在不同的上下文中使用时指的是不同的事物)。如果名称确实需要是
BAD
,请考虑为类或枚举使用封闭的命名空间或类(最好使用枚举)。This is one of those tricky parts of how the name lookup is performed.
There are two identifier scopes in C++, one for class types and general identifier scope. The enum value BAD resides in the general identifier scope, while the class type BAR resides in the class identifier scope. That is the reason why you are allowed to have both an enum value and a class with the same name: both names do not collide.
Within class BAD, the identifier lookup rules will find the class BAD before it finds the enum, and thus the error. Now, if you fully qualify the identifier then the name lookup will first check the global identifier scope and match the enum value. On the opposite end, you will have to add the
struct
orclass
keyword to declare variables of type BAD.Now, I would advice against this usage. It is generally not a good idea to reuse an identifier like this. Code will be more complex, and probably misleading for the casual reader (the same unqualified identifier refers to different things when used in different contexts). If the names do need to be
BAD
, consider using an enclosing namespace or class for either the class or the enum (prefer the enum there).或者如果您位于全局命名空间中,
但我不建议使用该名称重载。 C++0X 将允许
如果对 C++0X 的依赖性可以接受,
哪个是更好的解决方案。正如所承诺的,解释
9.1/2
elaborated-type-specifier 的形式是
这样,这是为了与 C 兼容,其中标记名称位于不同的命名空间中,并且必须是 [i]typedef[/i]如果想在没有详细类型说明符的情况下使用它们,请编辑。 (一个众所周知的函数示例是 Unix 中的 struct stat 和函数 stat)。
这就解释了为什么可以重载名称来指定类和枚举器。 BAD 在这里指定类的原因是类的名称也定义到类作用域中,并且在成员函数定义中搜索的作用域是按顺序排列的:
- 成员函数作用域
- 类范围
- 包含类定义
BAD 的命名空间在类范围内找到,因此永远不会搜索命名空间 foo。
or if you are in the global namespace
but that name overloading is not something I'd recommend. C++0X will allow
which is a better solution if the dependency on C++0X is acceptable.
As promised, the explanation
9.1/2
The elaborated-type-specifier is the form
This is for compatibility with C where tag names are in a different name space and must be [i]typedef[/i]ed if one want to use them without an elaborated-type-specifier. (A well known example with a function is the struct stat and the function stat in Unix).
That explain why the overloading of a name to designate a class and an enumerator is possible. The reason for which BAD designate the class here is that the name of the class is also defined into the class scope and in a member function definition the scope searched are in order:
- the member function scope
- the class scope
- the namespace containing the class definition
BAD is found at class scope, so the namespace foo is never searched.
不,没有办法做到这一点。您应该使用有效的标识符。有效标识符意味着您必须能够识别它。 :)
No, there is no way to do that. You should use valid identifier. Valid identifier means that you have to be able to identify with it. :)
这在 VS2008 中有效,但给出了一个警告:
它不是我可以推荐的。
您应该将枚举放在
foo
内的另一个命名空间中,并使用新命名空间限定bar
和BAD
。This works in VS2008, but gives a warning:
Its not something I can recommend.
You should put the enum within another namespace inside
foo
and qualify bothbar
andBAD
with the new namespace.