5

取消引用类型双关语

我有一个枚举

enum AgentStatus { kSTOPPED = 0, kRUNNING, kIDLE, kNAGENTSTATUS };

我需要将它传递给具有许多重载变体的外部库的函数。我想将它传递给第二个参数:

DimService::DimService(const char*, int&);
DimService::DimService(const char*, char*);
...

如果我对枚举变量的 (int&) 进行强制转换,我会收到臭名昭著的警告:

warning: dereferencing type-punned pointer will break strict-aliasing rules

如果我对 (int) 进行强制转换,我会得到这个

invalid conversion from ‘int’ to ‘char*’
error:   initializing argument 2 of ‘DimService::DimService(const char*, char*)’

正确的方法是什么?

4

2 回答 2

8

当您在使用内联转换时遇到问题时,将其拆分为单独的行会很有帮助:

const AgentStatus enumValue = kRUNNING;
...
int intValue = static_cast<int>(enumValue);
DimService("works now", intValue);
于 2013-02-15T14:58:06.920 回答
6

比尔的答案在技术上是正确的答案。

1)另一种方法

如果您需要摆脱类型的枚举,另一种方法是使类型本身成为 int。

typedef int MyEnum;
enum
{
    CONST1 = 0,
    etc...
};

然后像平常一样使用它。编译器不会捕获错误的值分配,但是由于您可以将所有声明标记为 MyEnum 类型,它应该足够简单以跟踪正在发生的事情,并且您可以将变量传递到它所说的任何地方 int。

2) 危险的方法

永远不要这样做!

EnumType v = EnumValue_...

MyFunction( *((int*)&v) );

或这个...

#define MAKE_INT_REF(v) *((int*)&(v))

MyFunction( MAKE_INT_REF(v) );

原因是编译器可以自动选择枚举使用的类型。它可能会选择 int,也可能会选择 char。您无法确定跨不同的编译器和平台。因此,如果您尝试强制转换枚举,您最终会得到不可移植的代码和非常危险的代码,因为写回这样的强制转换会覆盖其他值。

于 2013-02-15T15:08:34.810 回答