如何在对int和作用域枚举的引用之间进行static_cast

How to static_cast between references to int and scoped enum?

本文关键字:之间 引用 static cast 枚举 int 作用域      更新时间:2023-10-16

我有以下枚举和输入流运算符:

enum class MsrEncryptionStatus : unsigned char
{
   Unknown = 0xFF,
   None = 0,
   Ksn,
   Dukpt,
   Other
};
inline std::istream& operator>>(std::istream& s, MsrEncryptionStatus& status)
{
   return s >> static_cast<unsigned&>(status);
}

由于我执行强制转换的方式,operator>>的上述实现没有编译。Clang抱怨:

main.cpp:34:16: error: non-const lvalue reference to type 'unsigned int' cannot bind to a value of unrelated type 'MsrEncryptionStatus'
   return s >> static_cast<unsigned&>(status);
               ^                      ~~~~~~

我要做的是避免定义一个变量来临时保存输入流中的值,然后再static_cast。有人能帮我理解我在这里错过了什么吗?我觉得我错过了static_cast如何在左值上运行的一个基本部分,例如,它感觉像是在这里创建了一个临时的,如果这是真的,我就不能将它绑定到一个非常量的左值引用。

我的编译器也拒绝进行静态转换,但由于您的其他义务,临时变量无论如何都更好。

您需要读取该值,根据MsrEncryptionStatus对其进行验证,然后将其分配给status或设置故障位。

以下是来自cppreference 的推荐模板

std::istream& operator>>(std::istream& is, T& obj)
{
    // read obj from stream
    if( /* T could not be constructed */ )
        is.setstate(std::ios::failbit);
    return is;
}

没有从MsrEncryptionStatus到unsigned int&的安全转换;。这就是static_cast失败的原因。如果你完全确定自己在做什么,你可以使用reinterpret_cast。

在下一个例子中,我将向您展示represet_cast有多危险:

int main( )
{
    std::ifstream i( "input.dat" ) ;
    unsigned a ;
    unsigned char b ;
    i >> a ;
    i >> reinterpret_cast<unsigned&>(b) ; // What was I thinking when I wrote this?
    std::cout << a << " " << b << std::endl ;
    return 0 ;
}

如果input.dat的内容为:

1234 5678

结果将类似于:

22 .

这证明你已经覆盖了堆栈。