C++中关于枚举的问题

4

我尝试在for循环中使用枚举,代码如下:

enum foo
{
    foo_0, 
    foo_1,
    foo_2,
    foo_3,
    ...
    foo_n,
    foo_count
};

for(foo f = foo_0; f < foo_count; ++f) 

我遇到了一个编译错误。我知道这是无效的,因为++f可能不是有效的foo枚举 - 在这种情况下不是通用情况,所以我将for循环改成了这样:

for(foo f = foo_0; f < foo_count; f = foo(f+1)) 

这段代码可以成功编译。但是这引发了以下问题:如果我有以下语句会怎样?

foo f = foo(k); //k is not a valid foo value

这算不确定行为吗?
编辑:k是一个整数,在foo中没有对应的值。
编辑2:
enum foo
{
    foo_0, 
    foo_1,
    foo_2,
    foo_3
};

foo f = foo(100); //what value will have f after this according to the standard

感谢您的帮助!
3个回答

7

我遇到了编译错误。我明白这是无效的,因为++f可能不是有效的foo枚举。

不,那是错误的解释。它无法编译是因为foo类型没有定义operator++

如果你定义operator++如下:

foo & operator++(foo & f) 
{  
   return f = foo(f+1); 
}

然后++f将编译并工作:http://ideone.com/1GG09 至于foo(f + 1)(或foo(k)),那就没问题了。在内部,foo是一种整数类型。它的值可以是由基础整数类型表示的任何东西。
第7.2/6节说:
对于枚举,其中emin是最小的枚举器,emax是最大的枚举器,枚举的值是基础类型的值,在该范围内的 bmin 到b max ,其中bmin 和b max 分别是可以存储emin 和emax 的最小位字段的最小值和最大值)。可以定义一个枚举,其具有未由任何枚举器定义的值。
编辑:
 foo f = foo(100); //what value will have f after this according to the standard

我认为这里的行为是未指定的,因为标准在§7.2/9中规定:

算术类型或枚举类型的表达式可以显式转换为枚举类型。如果其值在枚举类型的枚举值范围内,则值不变;否则,得到的枚举值是未指定的。

关于枚举范围,请参见上面的引语。


我想说,++运算符不能被定义为枚举的默认运算符,因为它的行为无法为每个枚举类型都定义得很好。我的问题是,当我尝试使用无效的int值初始化枚举类型时会发生什么。 - Mircea Ispas
@Felics:无效的整数?我也评论了那部分。 - Nawaz
我有一个枚举,其内部值为0、1、2,我尝试使用整数3进行初始化。 - Mircea Ispas
1
@Felics,你最终会得到一个在枚举中未定义的枚举值,这在C++规则下是可以的,但对于你的程序来说可能不太理想。枚举值没有运行时检查。 - zneak
我将删除“接受答案”的选项,直到我的第二个编辑案例变得清晰起来,以保持此问题处于开放状态。 - Mircea Ispas
显示剩余6条评论

4

这是定义行为。如果k超出foo值的范围,则最终在f中的值是未指定的,并且如果kfoo值的范围内,则与k相同。

foo的范围是0 .. 2^(ld(n+2)+1) - 1,即可以存储所有枚举常量(enumerator)值的位字段的值。


0
在这种情况下,f的值将为k,但这与enum中的标签不对应。将enum视为unsigned int作为数据类型(除非另有设置),并将enum内部的标识符视为常量。

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