简体   繁体   English

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

[英]How does multiplication work for C++ enums?

We have a template conversion function intended for use with numeric datatypes. 我们有一个模板转换函数,用于与numeric数据类型一起使用。 Inside it contains a construct that makes it not compile with types like pointers. 它里面包含一个构造,它不能用像指针这样的类型进行编译。

template<class To, class From>
To ConvertTo( From what )
{
    assert( 2 * what == what * 2 ); // this will not compile for pointers
    //skipped
}

This function compiles and works allright when a enum is passed as the second template parameter: 当枚举作为第二个模板参数传递时,此函数可以编译并正常工作:

enum TSomeEnum {
   SE_First,
   SE_Second       
};

TSomeEnum enumValue = SE_First;
int result = ConvertTo<int>( enumValue );

The above code compiles and runs as intended on VC++7. 上面的代码在VC ++ 7上按预期编译和运行。

How does the operation * work for enums? 操作*如何用于枚举? Is it a way to undefined behaviour? 这是未定义行为的一种方式吗?

Enums degrade to ints (old C feature) so that why this is working. 枚举降级为整数(旧C功能),这就是为什么这是有效的。 I don't think it's undefined behaviour although it might be the sort of behaviour you don't want/expect. 我不认为它是未定义的行为,尽管它可能是你不想要/期望的那种行为。

Enums are promoted to integers for arithmetic operations. 枚举被提升为算术运算的整数。

The values of enums are always numbered up from zero (this is part of the standard), but you can specify whatever values you like. 枚举值始终从零开始编号(这是标准的一部分),但您可以指定您喜欢的任何值。 Automatic numbering then procedes incrementally from the last item you explicitly numbered. 然后自动编号从您明确编号的最后一个项目开始逐步进行。 The compiler uses the smallest integral type that contains all of the values of an enum to store it. 编译器使用包含枚举的所有值的最小整数类型来存储它。

eg: 例如:

enum foo
{
    VALUE0, /* = 0 */
    VALUE1, /* = 1 */
    VALUE3 = 1234,
    VALUE4  /* = 1235 */
};

I think peterchen has the ideal answer, but if boost is too much for you, change your current version to: 我认为peterchen有理想的答案,但如果对你来说太大了,请将当前版本更改为:

template<class To, class From>
To ConvertTo( From what, From checkConvertableToInt = 2 )
{
}

C++ doesn't allow implicit conversions from integers to enumerations. C ++不允许从整数到枚举的隐式转换。 Similarly, it's only possible to implicitly convert the null pointer constant (0) to a pointer type. 类似地,它只能隐式地将空指针常量(0)转换为指针类型。

Some of the other answers refer to an enumeration being implemented as an int or being promoted to an int. 其他一些答案指的是枚举被实现为int或被提升为int。 This is not true. 这不是真的。 In C++, an enumeration is defined to have an underlying type that is capable of storing all values in the enumeration. 在C ++中,枚举被定义为具有能够在枚举中存储所有值的基础类型。 The following enumeration will therefore have an underlying type of 'unsigned int' or a larger signed/unsigned integral type: 因此,以下枚举将具有基础类型“unsigned int”或更大的有符号/无符号整数类型:

enum E {
  E0
  , E1=MAX_INT+1u
};

The enumeration then follows the rules for its underlying type when you use it in an operation. 然后,当您在操作中使用枚举时,枚举将遵循其基础类型的规则。

Timo described why it works. 蒂莫描述了它的工作原理。

For a safer test, you could use boost::TypeTraits 为了更安全的测试,您可以使用boost::TypeTraits

Richard Corden's answer gives a good mechanism to force enums to fail in the assert, however the side effect can cause problems, as you cannot be sure the code inside the assert will always run. 理查德科登的答案提供了一个很好的机制来强制枚举在断言中失败,但副作用可能会导致问题,因为你不能确定断言中的代码将始终运行。

This test should probably by placed in a generic function to avoid the side effects. 这个测试应该放在一个通用函数中,以避免副作用。

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 );
}

enums are stored as integers, and can even be cast to integers. 枚举存储为整数,甚至可以转换为整数。

The compiler probably stored your above enum as 编译器可能将您的上述枚举存储为

enum TSomeEnum {
   SE_First = 0,
   SE_SEcond = 1
};

I'm not sure if this numbering system is part of the C/C++ standard or just how compilers do it, but I've always seen them in order. 我不确定这个编号系统是否是C / C ++标准的一部分,或者编译器是如何做到的,但我总是按顺序看到它们。

Anyway, to answer your question, since they're stored as ints underneath, it should be able to be multiplied. 无论如何,要回答你的问题,因为它们被存储为下面的int,它应该能够成倍增加。 Some compilers may give you a warning about type conversion though. 有些编译器可能会给出关于类型转换的警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM