将函数指针强制转换为noexcept指定的函数指针

use*_*108 6 c++ function-pointers noexcept

说我有这些声明:

using fp_type = void(*)();
using fp2_type = void(*)() noexcept;
Run Code Online (Sandbox Code Playgroud)

void func(){}
fp_type fp(func);
Run Code Online (Sandbox Code Playgroud)

演员fp2_type(fp)表现良好吗?反过来(将noexcept指定的函数指针强制转换为没有noexcept说明符的函数指针)?

T.C*_*.C. 5

这在 C++14 及更早版本中格式错误:

using fp2_type = void(*)() noexcept;
Run Code Online (Sandbox Code Playgroud)

由于 N4140 [except.spec]/2:

一个异常规范,不得出现在typedef声明或别名声明

所以我将假设问题是针对 C++1z 的,其中异常规范是类型系统的一部分。


[conv.fctptr]/1 :

noexcept函数指针”类型的纯右值可以转换为“函数指针”类型的纯右值。结果是一个指向函数的指针。

因此,void (*)() noexcept可以(隐式)转换为void (*)()

[expr.static.cast]/7 :

任何不包含 [(省略各种其他情况)] 函数指针 ([conv.fctptr]) 转换的标准转换序列 (Clause [conv]) 的反转,都可以使用 显式执行static_cast

[expr.static.cast] 中的任何其他内容都不允许转换void (*)()void (*)() noexcept任何一个,因此这不是可以由static_cast.

[expr.reinterpret.cast]/6 :

函数指针可以显式转换为不同类型的函数指针。通过指向与函数定义中使用的类型不同的函数类型([dcl.fct])的指针调用函数的效果是未定义的。除了将“pointer to T1”类型的纯右值转换为“pointer to ”类型 T2(其中T1T2是函数类型)并返回其原始类型会产生原始指针值之外,这种指针转换的结果是未指定的。[ 注意:另请参阅 [conv.ptr] 以了解指针转换的更多详细信息。— 尾注 ]

所以reinterpret_cast可以执行这个转换。

由于fp2_type(fp)等效于 C风格的强制转换(fp2_type) fp( [expr.type.conv]/1 ),并且由于 C 风格的强制转换做一个reinterpret_castwhenstatic_cast是不可能的const_cast为了简单而忽略,因为它在这里不相关),fp2_type(fp)是一个格式良好的reinterpret_cast. 然而,这种强制转换的结果不能被使用,除非将它强制转换回来。