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说明符的函数指针)?
这在 C++14 及更早版本中格式错误:
using fp2_type = void(*)() noexcept;
Run Code Online (Sandbox Code Playgroud)
由于 N4140 [except.spec]/2:
一个异常规范,不得出现在typedef声明或别名声明。
所以我将假设问题是针对 C++1z 的,其中异常规范是类型系统的一部分。
“
noexcept函数指针”类型的纯右值可以转换为“函数指针”类型的纯右值。结果是一个指向函数的指针。
因此,void (*)() noexcept可以(隐式)转换为void (*)()。
任何不包含 [(省略各种其他情况)] 函数指针 ([conv.fctptr]) 转换的标准转换序列 (Clause [conv]) 的反转,都可以使用 显式执行
static_cast。
[expr.static.cast] 中的任何其他内容都不允许转换void (*)()为void (*)() noexcept任何一个,因此这不是可以由static_cast.
函数指针可以显式转换为不同类型的函数指针。通过指向与函数定义中使用的类型不同的函数类型([dcl.fct])的指针调用函数的效果是未定义的。除了将“pointer to
T1”类型的纯右值转换为“pointer to ”类型T2(其中T1和T2是函数类型)并返回其原始类型会产生原始指针值之外,这种指针转换的结果是未指定的。[ 注意:另请参阅 [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. 然而,这种强制转换的结果不能被使用,除非将它强制转换回来。