C++17 异常说明符类型系统将如何工作?
How will C++17 exception specifier type system work?
学习一下"noexcept specifier(and operator)",写了个简单的代码。我很惊讶这段代码:
void asdf() noexcept {}
int main()
{
auto f = asdf;
std::cout << std::boolalpha << noexcept(f()) << std::endl;
}
打印 false
,甚至函数 "asdf" 也没有指定。
所以在寻找为什么会发生这种神秘现象时,我发现了 C++17 的 "exception specifier type system"- P0012R1.
根据这个(已接受的)提案,自 C++17 起;由于 noexcept
是函数类型的一部分,上面的代码会打印 true
?
还有一个,在问题的一行中:
std::function<void() noexcept> f
noexcept
指定在 C++14 或 11 中似乎被忽略了。
此代码在 C++17 中是否会按预期工作?
According to this (accepted) proposal, since C++17; as noexcept is part of function type, will the code above print true
?
是。
f
的类型将被推断为 void(*)() noexcept
,因为应用于 asdf
的函数到指针的转换将保留 noexcept
属性 .对 noexcept
函数指针的调用肯定不会抛出异常,除非它的子表达式之一抛出异常。
确切的措辞,参见[expr.unary.noexcept]/3 and [expect.spec]/13。请注意,C++17 草案后一段中的新措辞来自 P0012R1,在 OP 中有链接。
The result of the noexcept
operator is true
if the set of potential exceptions of the expression ([except.spec]) is empty, and false
otherwise.
...
- If
e
is a function call ([expr.call]):
- If its postfix-expression is a (possibly parenthesized) id-expression ([expr.prim.id]), class member access ([expr.ref]), or pointer-to-member operation ([expr.mptr.oper]) whose cast-expression is an id-expression, S is the set of types in the exception specification of the entity selected by the contained id-expression (after overload resolution, if applicable).
...
所以 f()
的潜在异常集与 f
的异常规范中的类型集相同,后者是空的,因为 f
被声明为 [=14] =].
我们继续第二个问题:
The noexcept
specifying seems ignored in C++14 or 11. Will this code work as intended in C++17?
您的问题似乎是:std::function<void() noexcept>
会拒绝持有可以抛出异常的函数吗?
我会说不清楚。在目前的标准措辞中,std::function<void() noexcept>
实际上并没有定义,就像std::function<double(float) const>
is not defined一样。这在 C++14 中当然不是问题,因为 noexcept
不被视为函数类型的一部分。
std::function<void() noexcept>
会在 C++17 中简单地中断吗?这对我来说是不确定的。让我们看一下当前的措辞来猜测 "should" 的行为是什么。
标准要求 std::function<R(ArgTypes..)>
的构造函数的参数为 "Lvalue-Callable" 参数类型 ArgTypes...
和 return 类型 R
,means:
A callable type ([func.def]) F
is Lvalue-Callable for argument types ArgTypes
and return type R
if the expression INVOKE(declval<F&>(), declval<ArgTypes>()..., R)
, considered as an unevaluated operand (Clause [expr]), is well formed ([func.require]).
也许应该有一个额外的要求,如果函数类型是noexcept
,那么noexcept(INVOKE(...))
也必须为真。尽管如此,这个措辞并没有出现在当前的草案中。
在P0012R1中,有一条评论是:
It is an open issue how to propagate "noexcept" through std::function
.
我的猜测是,他们的意思是,如果施加此附加要求,则不清楚如何实施 std::function
。希望其他人可以提供更多详细信息。
学习一下"noexcept specifier(and operator)",写了个简单的代码。我很惊讶这段代码:
void asdf() noexcept {}
int main()
{
auto f = asdf;
std::cout << std::boolalpha << noexcept(f()) << std::endl;
}
打印 false
,甚至函数 "asdf" 也没有指定。
所以在寻找为什么会发生这种神秘现象时,我发现了 C++17 的 "exception specifier type system"- P0012R1.
根据这个(已接受的)提案,自 C++17 起;由于 noexcept
是函数类型的一部分,上面的代码会打印 true
?
还有一个,在
std::function<void() noexcept> f
noexcept
指定在 C++14 或 11 中似乎被忽略了。
此代码在 C++17 中是否会按预期工作?
According to this (accepted) proposal, since C++17; as noexcept is part of function type, will the code above print
true
?
是。
f
的类型将被推断为 void(*)() noexcept
,因为应用于 asdf
的函数到指针的转换将保留 noexcept
属性 .对 noexcept
函数指针的调用肯定不会抛出异常,除非它的子表达式之一抛出异常。
确切的措辞,参见[expr.unary.noexcept]/3 and [expect.spec]/13。请注意,C++17 草案后一段中的新措辞来自 P0012R1,在 OP 中有链接。
The result of the
noexcept
operator istrue
if the set of potential exceptions of the expression ([except.spec]) is empty, andfalse
otherwise....
- If
e
is a function call ([expr.call]):
- If its postfix-expression is a (possibly parenthesized) id-expression ([expr.prim.id]), class member access ([expr.ref]), or pointer-to-member operation ([expr.mptr.oper]) whose cast-expression is an id-expression, S is the set of types in the exception specification of the entity selected by the contained id-expression (after overload resolution, if applicable). ...
所以 f()
的潜在异常集与 f
的异常规范中的类型集相同,后者是空的,因为 f
被声明为 [=14] =].
我们继续第二个问题:
The
noexcept
specifying seems ignored in C++14 or 11. Will this code work as intended in C++17?
您的问题似乎是:std::function<void() noexcept>
会拒绝持有可以抛出异常的函数吗?
我会说不清楚。在目前的标准措辞中,std::function<void() noexcept>
实际上并没有定义,就像std::function<double(float) const>
is not defined一样。这在 C++14 中当然不是问题,因为 noexcept
不被视为函数类型的一部分。
std::function<void() noexcept>
会在 C++17 中简单地中断吗?这对我来说是不确定的。让我们看一下当前的措辞来猜测 "should" 的行为是什么。
标准要求 std::function<R(ArgTypes..)>
的构造函数的参数为 "Lvalue-Callable" 参数类型 ArgTypes...
和 return 类型 R
,means:
A callable type ([func.def])
F
is Lvalue-Callable for argument typesArgTypes
and return typeR
if the expressionINVOKE(declval<F&>(), declval<ArgTypes>()..., R)
, considered as an unevaluated operand (Clause [expr]), is well formed ([func.require]).
也许应该有一个额外的要求,如果函数类型是noexcept
,那么noexcept(INVOKE(...))
也必须为真。尽管如此,这个措辞并没有出现在当前的草案中。
在P0012R1中,有一条评论是:
It is an open issue how to propagate "noexcept" through
std::function
.
我的猜测是,他们的意思是,如果施加此附加要求,则不清楚如何实施 std::function
。希望其他人可以提供更多详细信息。