static_cast可以在C++中抛出异常吗?

Hri*_*shi 10 c++ casting

假设static_cast永远不会抛出异常是否安全?

对于Enum强制转换的int,即使它无效,也不会抛出异常.我可以依靠这种行为吗?以下代码有效.

enum animal {
  CAT = 1,
  DOG = 2
};

int y = 10;
animal x = static_cast<animal>(y);
Run Code Online (Sandbox Code Playgroud)

In *_*ico 13

对于此特定类型的强制转换(枚举类型的组成部分),可能会抛出异常.

C++标准5.2.9静态强制转换[expr.static.cast]第7段

可以将整数或枚举类型的值显式转换为枚举类型.如果原始值在枚举值(7.2)的范围内,则该值不变.否则,生成的枚举值未指定/未定义(自C++ 17起).

请注意,由于C++ 17这样的转换实际上可能导致未定义的行为,这可能包括抛出异常.

换句话说,static_cast如果通过某种输入验证过程确保整数实际上表示有效的枚举值,那么从C++ 17开始,从整数中获取枚举值的特定用法就可以了.

有时输入验证程序完全消除了对a的需要static_cast,如下所示:

animal GetAnimal(int y)
{
    switch(y)
    {
    case 1:
        return CAT;
    case 2:
        return DOG;
    default:
        // Do something about the invalid parameter, like throw an exception,
        // write to a log file, or assert() it.
    }
}
Run Code Online (Sandbox Code Playgroud)

请考虑使用类似上述结构的东西,因为它不需要强制转换,并且让您有机会正确处理边界情况.


Rob*_*obᵩ 10

假设static_cast永远不会抛出异常是否安全?

对于用户定义的类型,构造函数和/或转换运算符可能会抛出异常,从而导致定义明确的行为.

考虑一下这个程序的输出:

#include <iostream>

struct A {
  A(int) { throw 1; }
};

int main () {
  int y = 7;
  try {
    static_cast<A>(y);
  } catch(...) {
    std::cout << "caught\n";
  }
}
Run Code Online (Sandbox Code Playgroud)


For*_*veR 7

static_cast不能抛出异常,因为static_cast不是运行时强制转换,如果有些不能被转换,代码将不会编译.但是如果它编译并且演员阵容很糟糕 - 结果是不确定的.

  • 这不一定是真的.对于源和目标类型的某些组合,它可能导致未定义的行为,并且所述*未定义的行为可能包括抛出异常*. (3认同)