【问题标题】:How to static cast throwing function pointer to noexcept in C++17?如何在 C++17 中将抛出函数指针静态转换为 noexcept?
【发布时间】:2019-08-22 01:15:16
【问题描述】:

C++17 使 noexcept 成为函数类型的一部分。它还允许从 noexcept 函数指针到潜在抛出函数指针的隐式转换。

void (*ptr_to_noexcept)() noexcept = nullptr;
void (*ptr_to_throwing)() = ptr_to_noexcept;  // implicit conversion

http://eel.is/c++draft/expr.static.cast#7 表示static_cast 可以执行这种转换的逆操作。

void (*noexcept_again)() noexcept = static_cast<void(*)() noexcept>(ptr_to_throwing);

不幸的是,GCC 和 clang 都告诉我:https://godbolt.org/z/TgrL7q

这样做的正确方法是什么? reinterpret_cast 和 C 风格转换是我唯一的选择吗?

【问题讨论】:

  • "reinterpret_cast 和 C 风格转换" 我的经验中。
  • 如果这个问题抛开对static_cast 的困惑并简单地问“我怎样才能投射这个?有什么危险?”。
  • 我故意不问危险是什么。这应该不会比 const_cast 更危险,其中原始对象被声明为非 const 或派生转换的基础,我知道我的基础引用实际上是指派生对象。我只担心这个noexcept演员需要reinterpret_cast的所有风险。

标签: c++ c++17 function-pointers static-cast noexcept


【解决方案1】:

你可能跳过了重要的部分:

任何标准转换序列的逆不包含左值到右值、数组到指针、函数到指针、空指针、空成员指针、布尔值、或函数指针转换,可以使用 static_cast 显式执行。

目前,函数指针转换仅包括从noexcept 到潜在抛出的转换。因为您正在执行函数指针转换的逆操作,所以 static_cast 将不起作用,就像您不能 static_cast 指向数组的指针或其中列出的任何其他转换一样。

所以,是的,reinterpret_cast 将是合适的,并且还引发了丢弃 noexcept 时应有的适当警钟。

【讨论】:

  • 您能否评论一下为什么将限制添加到static_cast
  • @Filipp,我没有什么比猜测更多的东西,但static_cast 倾向于远离更不安全的事情,并且通常在你需要一个不同类型的值时出现。我认为noexcept 类似于const 在这方面丢弃它会破坏之前做出的承诺,这可能会给读者带来严重的后果。大多数其他逆对 C++ 没有太大意义。让我感到困惑的是布尔转换。从 bool 到函数指针没有多大意义,但编译器允许 bool 到 static_cast 中的浮点类型。
猜你喜欢
  • 2016-06-03
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2023-04-03
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
相关资源
最近更新 更多