suh*_*hwi 20 c++ noexcept c++11 c++14 c++17
在研究"noexcept说明符(和运算符)"时,我写了一个简单的代码.我对这段代码感到惊讶:
void asdf() noexcept {}
int main()
{
auto f = asdf;
std::cout << std::boolalpha << noexcept(f()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
打印false,甚至函数"asdf"是noexcept指定的.
因此,在搜索为什么会发生这种神秘现象时,我发现了C++ 17的"异常说明符类型系统" - P0012R1.
根据这个(接受的)提议,自C++ 17以来; 作为noexcept功能类型的一部分,上面的代码会打印true吗?
还有一个,在这个问题的一行中:
std::function<void() noexcept> f
Run Code Online (Sandbox Code Playgroud)
noexcept在C++ 14或11中,指定似乎被忽略了.这个代码是否会像C++ 17中那样工作?
Bri*_*ian 11
根据这个(接受的)提议,自C++ 17以来; 因为noexcept是函数类型的一部分,上面的代码会打印
true吗?
是.
由于应用的函数到指针转换将保留属性,f因此将推断出类型.对函数指针的调用当然不能抛出异常,除非它的一个子表达式.void(*)() noexceptasdfnoexceptnoexcept
有关确切的措辞,请参阅[expr.unary.noexcept]/3和[expect.spec]/13.请注意,C++ 17草案后一段中的新措辞来自P0012R1,它在OP中链接.
noexcept运算符的结果是true表达式([except.spec])的潜在异常集是否为空,false否则为空....
- 如果
e是函数调用([expr.call]):
- 如果它的postfix-expression是一个(可能带括号的)id-expression([expr.prim.id]),类成员访问([expr.ref])或指向成员的操作([expr.mptr.oper] )其cast-expression是一个id-expression,S是由包含的id-expression选择的实体的异常规范中的类型集(在重载解析之后,如果适用)....
因此,潜在异常f()集与异常规范中的类型集相同,f自f声明后为空noexcept.
让我们继续讨论第二个问题:
noexcept在C++ 14或11中,指定似乎被忽略了.这个代码是否会像C++ 17中那样工作?
你的问题似乎是:会std::function<void() noexcept>拒绝持有可以抛出异常的函数吗?
我会说现在还不清楚.在目前的标准措辞中,std::function<void() noexcept>实际上没有定义,正如std::function<double(float) const>未定义的那样.这当然不是C++ 14中的问题,因为noexcept它不被认为是函数类型的一部分.
将std::function<void() noexcept>简单地打破C++ 17?这对我来说不确定.让我们看看当前的措辞来猜测"应该"的行为.
该标准要求构造函数的std::function<R(ArgTypes..)>参数为参数类型ArgTypes...和返回类型的"Lvalue-Callable" R,这意味着:
可调用类型([func.def])对于参数类型
F是Lvalue -Callable,如果被认为是未评估的操作数(Clause [expr])的表达式格式正确([func.require]),则ArgTypes返回类型.RINVOKE(declval<F&>(), declval<ArgTypes>()..., R)
也许应该有一个额外的要求,如果函数类型是noexcept,那么也noexcept(INVOKE(...))必须是真的.尽管如此,目前的草案中并没有这种措辞.
在P0012R1中,有一条评论:
如何传播"noexcept"是一个悬而未决的问题
std::function.
我的猜测是,他们的意思是,std::function如果实施这一额外要求,目前尚不清楚如何实施.希望其他人可以提供更多细节.