typedef 枚举不会使枚举值可见
我有一个类,其中有一个枚举,定义如下:
class X
{
public:
enum Direction {DIR_LEFT, DIR_RIGHT};
};
现在我希望在另一个类中重用此枚举,如下所示:
class Y
{
public:
typedef X::Direction Direction;
};
正如预期的那样,使用 Y::Direction 可以正常工作,例如:
void myFunction (Y::Direction dir)
{
}
但枚举中的值确实似乎没有与 typedef 一起“复制”。如果我编写以下内容,则会出现编译错误:
myFunction (Y::DIR_LEFT);
相反,我必须再次引用枚举的原始位置,如下所示:
myFunction (X::DIR_LEFT);
这违背了我对枚举进行类型定义的目的。
我看到的唯一解决方案是将枚举移出类 X,并将其放入另一个类(例如 MyEnums)中,以便 X 和 Y 可以重用它(尽管它们仍然应该使用 MyEnums::DIR_LEFT 和 MyEnums::DIR_RIGHT ),但至少代码不再依赖于 X 类。
为什么枚举值本身不通过 typedef 公开?
是否有其他模式来管理不同类中的枚举?
I have a class in which I have an enumeration, defined like this:
class X
{
public:
enum Direction {DIR_LEFT, DIR_RIGHT};
};
Now I want this enumeration to be reused in another class, like this:
class Y
{
public:
typedef X::Direction Direction;
};
As expected, using Y::Direction works correctly, e.g.:
void myFunction (Y::Direction dir)
{
}
But the values within the enumeration does not seem to be 'copied' together with the typedef. If I write the following, I get compilation errors:
myFunction (Y::DIR_LEFT);
Instead, I have to refer to the original place of the enumeration again, like this:
myFunction (X::DIR_LEFT);
Which defeats my purpose of typdefing the enumeration.
The only solution I see is to move the enumeration out of class X, and putting it in another class (e.g. MyEnums), so it can be reused by X and Y (although they should still use MyEnums::DIR_LEFT and MyEnums::DIR_RIGHT), but at least the code does not depend on class X anymore.
Why are the enumeration values itself no exposed via the typedef?
Are there any other patterns to manage enumerations in different classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不幸的是,尽管 C++0x 正在改进一些东西,但 C++ 并没有引入带有
enum
的新作用域。实际上,这意味着您无法键入定义枚举并获取枚举值。
您可以做的是使用嵌套结构以及您想要的枚举和typedef名称。
现在你可以这样做:
myFunction (Y::Direction::LEFT);
嵌套结构的目的是创建一个“假”作用域来保存枚举名称及其值。
Unfortunately C++ doesn't introduce a new scope with an
enum
although C++0x is improving things.Practically this means that you can't typedef an enum and get the enumerated values as well.
What you can do is use a nested struct with the name you want for the enum and typedef THAT.
Now you can do:
myFunction (Y::Direction::LEFT);
The purpose of the nested struct is to create a "fake" scope to holld both the enum name and its values.
这是我对 C++ 中枚举如何工作的理解。 (或者至少是我在 Microsoft Visual C++ 中观察到的枚举行为。)
enum 关键字不会像类那样创建作用域。
枚举“Direction”的全名是 X::Direction。该枚举中的值仍然是类范围的一部分,因此它们是 X::DIR_LEFT 和 X::DIR_RIGHT。
当您在另一个类中键入 def 枚举时,这不会更改枚举值的范围。
如果您想在多个位置共享枚举,我建议您将枚举放在头文件的命名空间内。
Here is my understanding of how enums work in C++. (Or at least my observed behaviour of enums in Microsoft Visual C++.)
The enum keyword does not create a scope the same way that classes do.
The full name then for your enum 'Direction', is X::Direction. The values within that enum are still part of the class scope, so they are X::DIR_LEFT and X::DIR_RIGHT.
When you typedef the enum in another class, this does not change the scope of the values of the enum.
I suggest you put the enum inside a namespace in a header file if you want to share it in multiple locations.
如果您希望枚举值成为两个类的成员,则
解决方案是使用枚举定义一个单独的类,并且
继承它,例如:
用户将看到 X::Direction、X::DIR_LEFT 和 Y::Direction,
Y::DIR_LEFT。当然,他们仍然能够通过
Y::DIR_LEFT 到需要 X::Direction 的函数;到
防止这种情况发生,使 MyEnums 成为模板,派生类为
模板参数。
If you want the enum values to be members of both classes, the
solution is to define a separate class with the enum, and
inherit from it, e.g.:
Users will see X::Direction, X::DIR_LEFT and Y::Direction,
Y::DIR_LEFT. Of course, they'll still be able to pass
a Y::DIR_LEFT to a function expecting an X::Direction; to
prevent that, make MyEnums a template, with the derived class as
the template argument.
任何由多个类共享的内容都应该被考虑到类之外,或许还应该考虑到父类中。
方向.hpp:
x.hpp:
y.hpp
Anything shared by more than one class should be factored outside of the classes and perhaps into a parent class.
direction.hpp:
x.hpp:
y.hpp
如果原始声明:
嵌入到大型遗留代码库中,那么我们可能需要一个不会改变 X::Direction 任何现有用途的解决方案。在这种情况下,相当丑陋的:
工作......
但是,绝对不推荐用于新代码!
If the original declaration:
is embedded in a large legacy code-base, then we might want a solution that does not change any existing uses of X::Direction. In that case, the rather ugly:
works...
Definitely not recommended for new code, however!