我们有一个模板转换函数,用于与numeric数据类型一起使用。它里面包含一个构造,它不能用像指针这样的类型进行编译。
template<class To, class From>
To ConvertTo( From what )
{
assert( 2 * what == what * 2 ); // this will not compile for pointers
//skipped
}
当枚举作为第二个模板参数传递时,此函数可以编译并正常工作:
enum TSomeEnum {
SE_First,
SE_Second
};
TSomeEnum enumValue = SE_First;
int result = ConvertTo<int>( enumValue );
上面的代码在VC ++ 7上按预期编译和运行。
操作*如何用于枚举?这是一种未定义行为的方式吗?
答案 0 :(得分:5)
枚举降级为整数(旧C功能),以便这可行。我不认为它是未定义的行为,尽管它可能是你不希望/期望的那种行为。
答案 1 :(得分:2)
枚举被提升为整数以进行算术运算。
枚举值始终从零开始编号(这是标准的一部分),但您可以指定您喜欢的任何值。然后自动编号从您明确编号的最后一个项目开始逐步进行。 编译器使用包含枚举的所有值的最小整数类型来存储它。
例如:
enum foo
{
VALUE0, /* = 0 */
VALUE1, /* = 1 */
VALUE3 = 1234,
VALUE4 /* = 1235 */
};
答案 2 :(得分:2)
我认为peterchen有理想的答案,但如果对你来说太大了,请将当前版本更改为:
template<class To, class From>
To ConvertTo( From what, From checkConvertableToInt = 2 )
{
}
C ++不允许从整数到枚举的隐式转换。类似地,它只能隐式地将空指针常量(0)转换为指针类型。
其他一些答案指的是枚举被实现为int或被提升为int。这不是真的。在C ++中,枚举被定义为具有能够在枚举中存储所有值的基础类型。因此,以下枚举将具有基础类型“unsigned int”或更大的有符号/无符号整数类型:
enum E {
E0
, E1=MAX_INT+1u
};
当您在操作中使用枚举时,枚举将遵循其基础类型的规则。
答案 3 :(得分:1)
描述其工作原理。为了更安全的测试,您可以使用boost::TypeTraits
答案 4 :(得分:1)
Richard Corden的回答提供了一个很好的机制来强制枚举在枚举中失败,但副作用可能会导致问题,因为你无法确定断言中的代码是否会一直运行。
这个测试应该放在一个通用函数中以避免副作用。
template<class To, class From>
To ConvertTo( From what )
{
assert( testIntegralType(what) );
}
template<class T>
void testIntegralType( T val )
{
T v1 = val;
assert( 2*v1 == 2*val );
}
答案 5 :(得分:0)
枚举存储为整数,甚至可以转换为整数。
编译器可能将上面的枚举存储为
enum TSomeEnum {
SE_First = 0,
SE_SEcond = 1
};
我不确定这个编号系统是否是C / C ++标准的一部分,或者编译器是如何做到的,但我总是按顺序看到它们。
无论如何,要回答你的问题,因为它们被存储为下面的int,它应该能够成倍增加。有些编译器可能会给你一个关于类型转换的警告。