将函数指针转换为 noexcept 指定的函数指针
Casting a function pointer into a noexcept specified function pointer
假设我有这些声明:
using fp_type = void(*)();
using fp2_type = void(*)() noexcept;
和
void func(){}
fp_type fp(func);
演员表fp2_type(fp)
是否合式?反过来(将 noexcept 指定的函数指针转换为没有 noexcept 说明符的函数指针)?
这在 C++14 和更早版本中是错误的:
using fp2_type = void(*)() noexcept;
由于 N4140 [except.spec]/2:
An exception-specification shall not appear in a typedef declaration or alias-declaration.
所以我假设问题是针对 C++1z 的,其中异常规范是类型系统的一部分。
A prvalue of type “pointer to noexcept
function” can be converted to
a prvalue of type “pointer to function”. The result is a pointer to
the function.
因此,void (*)() noexcept
可以(隐含地)转换为 void (*)()
。
The inverse of any standard conversion sequence (Clause [conv]) not
containing a [(various other cases omitted)] function pointer ([conv.fctptr]) conversion, can be performed
explicitly using static_cast
.
[expr.static.cast] 中的任何其他内容都不允许将 void (*)()
转换为 void (*)() noexcept
,因此这不是 static_cast
可以执行的转换。
A function pointer can be explicitly converted to a function pointer
of a different type. The effect of calling a function through a
pointer to a function type ([dcl.fct]) that is not the same as the
type used in the definition of the function is undefined. Except that
converting a prvalue of type “pointer to T1
” to the type “pointer to
T2
” (where T1
and T2
are function types) and back to its original type
yields the original pointer value, the result of such a pointer
conversion is unspecified. [ Note: see also [conv.ptr] for more
details of pointer conversions. — end note ]
因此 reinterpret_cast
可以执行此转换。
因为 fp2_type(fp)
等同于 C 风格的转换 (fp2_type) fp
([expr.type.conv]/1), and since C-style casts do a reinterpret_cast
when static_cast
is not possible(为简单起见忽略 const_cast
,因为它与此处无关),fp2_type(fp)
是一个格式正确的 reinterpret_cast
。但是,这种类型转换的结果不能使用,除非将其转换回去。
假设我有这些声明:
using fp_type = void(*)();
using fp2_type = void(*)() noexcept;
和
void func(){}
fp_type fp(func);
演员表fp2_type(fp)
是否合式?反过来(将 noexcept 指定的函数指针转换为没有 noexcept 说明符的函数指针)?
这在 C++14 和更早版本中是错误的:
using fp2_type = void(*)() noexcept;
由于 N4140 [except.spec]/2:
An exception-specification shall not appear in a typedef declaration or alias-declaration.
所以我假设问题是针对 C++1z 的,其中异常规范是类型系统的一部分。
A prvalue of type “pointer to
noexcept
function” can be converted to a prvalue of type “pointer to function”. The result is a pointer to the function.
因此,void (*)() noexcept
可以(隐含地)转换为 void (*)()
。
The inverse of any standard conversion sequence (Clause [conv]) not containing a [(various other cases omitted)] function pointer ([conv.fctptr]) conversion, can be performed explicitly using
static_cast
.
[expr.static.cast] 中的任何其他内容都不允许将 void (*)()
转换为 void (*)() noexcept
,因此这不是 static_cast
可以执行的转换。
A function pointer can be explicitly converted to a function pointer of a different type. The effect of calling a function through a pointer to a function type ([dcl.fct]) that is not the same as the type used in the definition of the function is undefined. Except that converting a prvalue of type “pointer to
T1
” to the type “pointer toT2
” (whereT1
andT2
are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. [ Note: see also [conv.ptr] for more details of pointer conversions. — end note ]
因此 reinterpret_cast
可以执行此转换。
因为 fp2_type(fp)
等同于 C 风格的转换 (fp2_type) fp
([expr.type.conv]/1), and since C-style casts do a reinterpret_cast
when static_cast
is not possible(为简单起见忽略 const_cast
,因为它与此处无关),fp2_type(fp)
是一个格式正确的 reinterpret_cast
。但是,这种类型转换的结果不能使用,除非将其转换回去。