【问题标题】:in which situations anonymous enum should be used?在哪些情况下应该使用匿名枚举?
【发布时间】:2012-04-14 20:38:38
【问题描述】:

在 c 和 c++ 中,enum 可以用标签定义

enum e_smth {
    smth_one,
    smth_two,
    smth_err
};

或不带标签

enum {
    smth_one,
    smth_two,
    smth_err
};

如果它是用标记定义的,那么在 c 和 c++ 中的 switch 语句中都是有意义的:

e_smth some_var;
....//do some stuff with some_var
switch (some_var)
{
case smth_one:
break;
case smth_two:
break;
}

如果使用 gcc 或 g++ 编译,将产生-Wswitch 警告。

在 c++ 中的函数声明和变量初始化是有意义的:

e_smth var;
var=99;

如果用 g++ 编译会产生-fpermissive 错误。

带或不带标记的两种类型都可以用作一个文件#define 不带参数的宏。


更新

可以作为一个文件使用#define不带参数的宏

意思是:不是在文件中写入#define MAX 1000,而是在文件范围内将MAX添加到全局使用enum { MAX=1000 }


那么匿名枚举呢,我只发现了一个用例: 像typedef enum { a,b,c } some_t; 这样的定义使它像带有标签的枚举一样工作

问题:

如果我还没有描述所有合理的用例,应该使用什么匿名枚举?

【问题讨论】:

  • 如果我没记错的话,我不确定我是否完全有这个,早在那天你不得不将 typedef 与 enum 一起使用,或者在声明变量时使用“enum”关键字枚举类型。一旦你有了 typedef,在枚举上加一个标签就无关紧要了,所以我们没有打扰。所以,tl;dr:古代历史的东西。
  • > 在声明变量时使用“enum”关键字这是旧的很好的 C 语法,但我已经纠正了问题,因为这里没有任何意义 @mjfgates

标签: c++ c


【解决方案1】:

在 C(但不是 C++)中,enum 可以 [ab] 用于定义 int 常量。

例如,给定这个声明:

const int MAX = 1024;

MAX 不是常量表达式,它是只读对象的名称。这意味着您不能在 case 标签中使用它,作为在文件范围或 static 声明的数组的大小,或在任何其他需要常量表达式的上下文中。

但是如果你写:

enum { MAX = 1024 };

那么MAX一个int类型的常量表达式,可以在任何可以使用常量1024的上下文中使用。

当然你也可以写:

#define MAX 1024

但是使用预处理器也有一些缺点:例如,标识符的作用域没有像普通声明那样。

缺点是这样的常量只能是int类型。

C++有不同的规则;枚举常量是枚举类型,不是int,但是你可以使用声明的常量对象作为常量表达式(只要初始化器是常量表达式)。

为了解决最初的问题,当您使用enum 声明来创建这样的常量时,使用标签或 typedef 是没有意义的,因为您永远不会使用类型本身。

背景:这个:

enum foo { zero, one, two };
enum foo obj = two;

创建一个类型enum foo 和常量zeroonetwo。在 C 中,常量总是int 类型,这无疑是奇怪的,obj 的初始化涉及从intenum foo 的隐式转换。

在C++中,enum foo类型也可以直接称为foo,常量是enum foo类型(兼容一些整数类型,不一定是@ 987654346@).

【讨论】:

  • enum 常量相对于#defines 的另一个(角落)优势是它们可以在宏扩展中定义。
【解决方案2】:

另一个用例是作为structunion 的一个元素,通常当它本身没有意义时(因为它只是为了满足通信协议等的ABI 和有更适合编程使用的表示)。

【讨论】:

  • 喜欢struct A {int a; enum{ e_a,e_b,e_c} state; }; ?
  • 是的,完全正确。在这种情况下没有真正的理由有标签。
【解决方案3】:

@eith 汤普森

您的答案是“const int MAX = 1024; MAX 不是常量表达式”。 但是,来自链接http://en.cppreference.com/w/cpp/language/constant_expression 的示例 表明它是一个常量表达式,可以在数组声明中使用。 常量表达式 C++ C++ 语言表达式 定义一个可以在编译时计算的表达式。

此类表达式可用作非类型模板参数、数组大小以及其他需要常量表达式的上下文,例如

int n = 1;
std::array<int, n> a1; // error, n is not a constant expression
const int cn = 2;
std::array<int, cn> a2; // OK, cn is a constant expression

【讨论】:

  • 我相信他指的是 C,而不是 C++。如果我没记错的话,C 的 const 规则比 C++ 的规则有点不稳定,因此使用 const 作为编译时常量是不合法的。
【解决方案4】:

通常,您只需要在多次使用枚举时为其命名。换句话说,如果您使用同一个枚举定义多个变量,那么您需要命名该枚举。但是,如果您只使用一次枚举并且只有一个变量具有该枚举,那么匿名枚举是有意义的。例如:

enum color { red, blue, gray, green };
enum color car_color;
enum color house_color;

这里有多个变量,所以命名为枚举。

typedef struct {
    int year;
    enum { Jan, Feb, Mar, Apr, May, Jun, July, Aug, Sep, Oct, Nov, Dec } month;
    unsigned int day;
} date;

这里作者打算只使用枚举一次,所以没有必要命名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 2011-11-01
    • 2019-08-05
    • 1970-01-01
    相关资源
    最近更新 更多