在哪种情况下应该使用匿名枚举?

时间:2012-04-14 20:38:38

标签: c++ c

在c和c ++中,enum可以使用标记

定义
enum e_smth {
    smth_one,
    smth_two,
    smth_err
};

或没有标记

enum {
    smth_one,
    smth_two,
    smth_err
};

如果使用tag定义它在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;这样的定义使其像标记

的枚举一样工作

问题:

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

4 个答案:

答案 0 :(得分:16)

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

例如,鉴于此声明:

const int MAX = 1024;

MAX不是常量表达式,它是只读对象的名称。这意味着您不能在案例标签中使用它,作为在文件范围或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(与某些兼容)整数类型,不一定是int)。

答案 1 :(得分:3)

另一个用例是作为structunion的元素,通常在单独使用它时没有意义(因为它只是为了满足通信协议的ABI)等等,并且有更合适的程序化使用表示。)

答案 2 :(得分:0)

@eith Thompson

您的回答是" 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

答案 3 :(得分:0)

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

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;

在这里,作者计划只使用一次枚举,因此不需要名称。

相关问题