Как статически бросить функцию броска указателя на noexcept в С++ 17?

С++ 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 моими единственными вариантами?

Ответы

Ответ 1

Возможно, вы пропустили важную часть:

Инверсия любой стандартной последовательности преобразования , не содержащей lvalue-to-rvalue, массив-указатель, функция-указатель, нулевой указатель, нулевой указатель на член, логическое значение, или преобразование указателя на функцию, можно выполнить явно, используя static_cast.

В настоящее время преобразование указателя функции включает в себя только преобразование из noexcept в потенциально выбрасываемый объект. Поскольку вы делаете обратное преобразование указателя на функцию, static_cast не будет работать, точно так же, как вы не можете static_cast указатель на массив или любое другое преобразование, перечисленное там.

Так что да, reinterpret_cast будет уместным, а также подает соответствующие сигналы тревоги, которые должны прийти с отбрасыванием noexcept.