typedef 枚举不会使枚举值可见

发布于 2024-10-21 20:10:52 字数 772 浏览 1 评论 0原文

我有一个类,其中有一个枚举,定义如下:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

并安 2024-10-28 20:10:52

不幸的是,尽管 C++0x 正在改进一些东西,但 C++ 并没有引入带有 enum 的新作用域。

实际上,这意味着您无法键入定义枚举并获取枚举值。

可以做的是使用嵌套结构以及您想要的枚举和typedef名称。

class X
{
public:
    struct Direction { enum EnumType {LEFT, RIGHT}; };
};

class Y
{
public:
    typedef X::Direction Direction;
};

现在你可以这样做:
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.

class X
{
public:
    struct Direction { enum EnumType {LEFT, RIGHT}; };
};

class Y
{
public:
    typedef X::Direction Direction;
};

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.

◇流星雨 2024-10-28 20:10:52

这是我对 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.

金兰素衣 2024-10-28 20:10:52

如果您希望枚举值成为两个类的成员,则
解决方案是使用枚举定义一个单独的类,并且
继承它,例如:

class MyEnums
{
protected:
    ~MyEnums() {} //  Prevent delete through pointer to this class
public:
    enum Direction
    {
        DIR_LEFT,
        DIR_RIGHT
    };
};

class X : public MyEnums
{
    // ...
};

class Y : public MyEnums
{
    // ...
};

用户将看到 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.:

class MyEnums
{
protected:
    ~MyEnums() {} //  Prevent delete through pointer to this class
public:
    enum Direction
    {
        DIR_LEFT,
        DIR_RIGHT
    };
};

class X : public MyEnums
{
    // ...
};

class Y : public MyEnums
{
    // ...
};

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.

岁月静好 2024-10-28 20:10:52

任何由多个类共享的内容都应该被考虑到类之外,或许还应该考虑到父类中。

方向.hpp:

#ifndef DIRECTION_HPP
enum Direction {DIR_LEFT, DIR_RIGHT};
#endif

x.hpp:

#ifndef X_HPP
#include "direction.hpp"

class X
{
  Direction dir;
};
#endif // X_HPP

y.hpp

#ifndef Y_HPP
#include "direction.hpp"

class Y
{
  Direction dir;
};
#endif // Y_HPP

Anything shared by more than one class should be factored outside of the classes and perhaps into a parent class.

direction.hpp:

#ifndef DIRECTION_HPP
enum Direction {DIR_LEFT, DIR_RIGHT};
#endif

x.hpp:

#ifndef X_HPP
#include "direction.hpp"

class X
{
  Direction dir;
};
#endif // X_HPP

y.hpp

#ifndef Y_HPP
#include "direction.hpp"

class Y
{
  Direction dir;
};
#endif // Y_HPP
捶死心动 2024-10-28 20:10:52

如果原始声明:

    class X
    {
    public:
      enum Direction {DIR_LEFT, DIR_RIGHT};
    };

嵌入到大型遗留代码库中,那么我们可能需要一个不会改变 X::Direction 任何现有用途的解决方案。在这种情况下,相当丑陋的:

    class Y
    {
    public:
       typedef enum X::Direction Direction;
       static const enum X::Direction DIR_LEFT = X:DIR_LEFT;
       static const enum X::Direction DIR_RIGHT = X:DIR_RIGHT;
    }

工作......

但是,绝对推荐用于新代码!

If the original declaration:

    class X
    {
    public:
      enum Direction {DIR_LEFT, DIR_RIGHT};
    };

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:

    class Y
    {
    public:
       typedef enum X::Direction Direction;
       static const enum X::Direction DIR_LEFT = X:DIR_LEFT;
       static const enum X::Direction DIR_RIGHT = X:DIR_RIGHT;
    }

works...

Definitely not recommended for new code, however!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文