我已经看到reinterpret_cast
用于将增量应用于枚举类,并且我想知道这种用法在标准C++中是否可以接受。
enum class Foo : int8_t
{
Bar1,
Bar2,
Bar3,
Bar4,
First = Bar1,
Last = Bar4
};
for (Foo foo = Foo::First; foo <= Foo::Last; ++reinterpret_cast<int8_t &>(foo))
{
...
}
我知道在琐碎的类的情况下强制转换为基类的引用是安全的。但是由于枚举类不会被事件隐式转换为它们的基础类型,因此我不确定上述代码是否以及如何保证在所有编译器中都能工作。有什么线索吗?
最佳答案
如果您确实想迭代其值,则可能希望为您的枚举重载运算符++
:
Foo& operator++( Foo& f )
{
using UT = std::underlying_type< Foo >::type;
f = static_cast< Foo >( static_cast< UT >( f ) + 1 );
return f;
}
和使用for (Foo foo = Foo::First; foo != Foo::Last; ++foo)
{
...
}
要回答是否允许
reinterpret_cast
的问题,所有这些都从5.2.10/1开始:(强调我的)
使用引用的重新解释基于5.2.10/11中的指针:
从而改变了这个问题:
reinterpret_cast<int8_t&>(foo)
是否合法:*reinterpret_cast<int8_t*>(&foo)
下一站是5.2.10/7:给定3.9/9,
int8_t
和您的枚举类型都是标准布局类型,现在该问题转换为:*static_cast<int8_t*>(static_cast<void*>(&foo))
这是您不走运的地方。 static_cast
是在5.2.9中定义的,没有使上述合法的东西-实际上5.2.9/5明确表明它是非法的。其他子句无济于事:T*
-> void*
-> T*
,其中T
必须相同(省略cv)我的结论是您的代码
reinterpret_cast<int8_t&>(foo)
不合法,其行为未由标准定义。还要注意,上述5.2.9/9和5.2.9/10负责使我在初始答案中给出的代码合法,您仍然可以在顶部找到它。
关于c++ - 将enum类变量reinterpret_cast转换为基础类型的引用是否安全?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19476818/