C++ 在类中声明枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2503807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:43:46  来源:igfitidea点击:

Declaring an enum within a class

c++classenumsnamespacesscope

提问by bporter

In the following code snippet, the Colorenum is declared within the Carclass in order to limit the scope of the enum and to try not to "pollute" the global namespace.

在以下代码片段中,Color枚举在Car类中声明,以限制枚举的范围并尽量不“污染”全局命名空间。

class Car
{
public:

   enum Color
   {
      RED,
      BLUE,
      WHITE
   };

   void SetColor( Car::Color color )
   {
      _color = color;
   }

   Car::Color GetColor() const
   {
      return _color;
   }

private:

   Car::Color _color;

};

(1) Is this a good way to limit the scope of the Colorenum? Or, should I declare it outside of the Carclass, but possibly within its own namespace or struct? I just came across this article today, which advocates the latter and discusses some nice points about enums: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums.

(1) 这是限制Color枚举范围的好方法吗?或者,我应该在Car类之外声明它,但可能在它自己的命名空间或结构中声明吗?我今天刚看到这篇文章,它提倡后者并讨论了一些关于枚举的好点:http: //gamesfromwithin.com/stupid-c-tr​​icks-2-better-enums

(2) In this example, when working withinthe class, is it best to code the enum as Car::Color, or would just Colorsuffice? (I assume the former is better, just in case there is another Colorenum declared in the global namespace. That way, at least, we are explicit about the enum to we are referring.)

(2)在本例中,工作时的类,它是最好的代码的枚举如Car::Color,还是只是Color足够?(我认为前者更好,以防万一Color在全局命名空间中声明了另一个枚举。这样,至少,我们明确了我们所指的枚举。)

采纳答案by Peter Alexander

  1. If Coloris something that is specific to just Cars then that is the way you would limit its scope. If you are going to have another Colorenum that other classes use then you might as well make it global (or at least outside Car).

  2. It makes no difference. If there is a global one then the local one is still used anyway as it is closer to the current scope. Note that if you define those function outside of the class definition then you'll need to explicitly specify Car::Colorin the function's interface.

  1. 如果Color是特定于Cars 的东西,那么这就是您限制其范围的方式。如果您打算Color使用其他类使用的另一个枚举,那么您最好将其设为全局(或至少在外部Car)。

  2. 没有什么不同的。如果有一个全局的,那么无论如何仍然使用本地的,因为它更接近当前范围。请注意,如果您在类定义之外定义这些函数,则需要Car::Color在函数的接口中明确指定。

回答by Andreas Florath

Nowadays - using C++11 - you can use enum classfor this:

如今 - 使用 C++11 - 您可以为此使用枚举类

enum class Color { RED, BLUE, WHITE };

AFAII this does exactly what you want.

AFAII 这正是您想要的。

回答by Sergey Teplyakov

I prefer following approach (code below). It solves the "namespace pollution" problem, but also it is much more typesafe (you can't assign and even compare two different enumerations, or your enumeration with any other built-in types etc).

我更喜欢以下方法(下面的代码)。它解决了“命名空间污染”问题,而且类型安全得多(您不能分配甚至比较两个不同的枚举,或者您的枚举与任何其他内置类型等)。

struct Color
{
    enum Type
    {
        Red, Green, Black
    };
    Type t_;
    Color(Type t) : t_(t) {}
    operator Type () const {return t_;}
private:
   //prevent automatic conversion for any other built-in types such as bool, int, etc
   template<typename T>
    operator T () const;
};

Usage:

用法:

Color c = Color::Red;
switch(c)
{
   case Color::Red:
     //некоторый код
   break;
}
Color2 c2 = Color2::Green;
c2 = c; //error
c2 = 3; //error
if (c2 == Color::Red ) {} //error
If (c2) {} error

I create macro to facilitate usage:

我创建宏以方便使用:

#define DEFINE_SIMPLE_ENUM(EnumName, seq) \
struct EnumName {\
   enum type \
   { \
      BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)\
   }; \
   type v; \
   EnumName(type v) : v(v) {} \
   operator type() const {return v;} \
private: \
    template<typename T> \
    operator T () const;};\

#define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) \
    BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),

Usage:

用法:

DEFINE_SIMPLE_ENUM(Color,
             ((Red, 1))
             ((Green, 3))
             )

Some references:

一些参考:

  1. Herb Sutter, Jum Hyslop, C/C++ Users Journal, 22(5), May 2004
  2. Herb Sutter, David E. Miller, Bjarne Stroustrup Strongly Typed Enums (revision 3), July 2007
  1. Herb Sutter,Jum Hyslop,C/C++ 用户杂志,22(5),2004 年 5 月
  2. Herb Sutter、David E. Miller、Bjarne Stroustrup 强类型枚举(修订版 3),2007 年 7 月

回答by Matthieu M.

In general, I always put my enums in a struct. I have seen several guidelines including "prefixing".

一般来说,我总是把我的枚举放在一个struct. 我看过一些指导方针,包括“前缀”。

enum Color
{
  Clr_Red,
  Clr_Yellow,
  Clr_Blue,
};

Always thought this looked more like Cguidelines than C++ones (for one because of the abbreviation and also because of the namespaces in C++).

一直认为这看起来更像是C指导方针而不是指导方针C++(因为缩写,也因为 中的命名空间C++)。

So to limit the scope we now have two alternatives:

因此,为了限制范围,我们现在有两种选择:

  • namespaces
  • structs/classes
  • 命名空间
  • 结构/类

I personally tend to use a structbecause it can be used as parameters for template programming while a namespace cannot be manipulated.

我个人倾向于使用 a ,struct因为它可以用作模板编程的参数,而不能操作命名空间。

Examples of manipulation include:

操纵的例子包括:

template <class T>
size_t number() { /**/ }

which returns the number of elements of enum inside the struct T:)

它返回结构内枚举的元素数T:)

回答by Harvey

If you are creating a code library, then I would use namespace. However, you can still only have one Color enum inside that namespace. If you need an enum that might use a common name, but might have different constants for different classes, use your approach.

如果您正在创建代码库,那么我将使用命名空间。但是,该命名空间中仍然只能有一个 Color 枚举。如果您需要一个可能使用通用名称的枚举,但对于不同的类可能有不同的常量,请使用您的方法。