乘法如何为C ++枚举工作?

时间:2009-07-28 11:48:07

标签: c++ templates

我们有一个模板转换函数,用于与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上按预期编译和运行。

操作*如何用于枚举?这是一种未定义行为的方式吗?

6 个答案:

答案 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,它应该能够成倍增加。有些编译器可能会给你一个关于类型转换的警告。