在命名空间中的枚举

23

做类似这样的事情有意义吗:

namespace status{
  enum status{
    ok,
    error
  };
}

然后像这样使用:status::ok

还是应该这样做:

enum status{
  status_ok,
  status_error
};

并像这样使用它 status_ok?

更新: 使用C++11,您现在应该这样做:

enum class status {
    ok,
    error
};

然后像这样使用:status::ok

5个回答

22

个人而言,我不喜欢第二种变体,因为对我来说status_部分似乎是多余的。前一版本避免了这个问题,但是有一个类型status::status看起来也很奇怪。此外,名称空间是可以修改的,所以如果有人做了类似于

namespace status {
  void error( const char *msg );
}

如果你使用 error 函数,会导致与你的 enum 值发生冲突而导致编译错误。

我更喜欢使用第三个变量:

struct MouseButton {
  enum Value {
    Left, Middle, Right
  };
};

这让我可以编写类似以下的函数:

void handleMouseButton( MouseButton::Value b ) {
  switch ( b ) {
    case MouseButton::Left:   // ...
    case MouseButton::Middle: // ...
    case MouseButton::Right:  // ...
  }
}

7

当启用C++0x扩展时,您想要的内容已经添加到C++中。然而,如果您无法使用C++0x功能,我建议您这样做:

struct status
{
    enum value
    {
        ok,
        error
    };
};

通过这样的声明,您可以编写以下内容:

status::value var = status::ok;

这样的结构还可以让你在struct作用域内声明与状态类型相关的函数。例如,状态struct可以包含将其转换为字符串/从字符串中转换回来的方法。

而且,这个解决方案允许你将枚举声明嵌套在类或结构体内部,而使用命名空间则不可能实现。 - neodelphi

4
如果您不担心使用“枚举状态”类型,那么可以将其保持匿名。请保留HTML标记。
namespace status{
  enum {  // <--- no name
    ok,
    error
  };
}

1
首先,您应该使用作用域运算符::而不是点运算符.来访问enum,即status::ok
两种方式都可以,取决于您认为哪种更易读。请注意,您也可以在不使用namespace的情况下使用。
enum status{
   ok,
   error
}

仍然使用status::ok,但一些编译器会警告您多余的status::是不必要的。

编辑:使用::访问enum似乎只适用于MS Visual-C++。


不,这是一个错误。编译器说status必须是命名空间或类/结构体。 - visitor
我用g++、icc、icpc进行了测试,结果确实出现了错误。然而,使用MS VS2010编译却没有问题。我还以为自己写的是很好移植的代码呢 ;) - Dan
2
在C++03中,这是一种非标准的MSVC扩展,但在C++11中它是标准的。 - ymett

1

我更喜欢使用命名空间的方法,因为它允许在代码片段中只使用一个枚举时,使用using namespace和使用较短的枚举值。

这主要是个人偏好的问题,然而,我认为在C++中解决(潜在的)名称冲突最好使用命名空间,因为这是使用命名空间的初衷。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接