Yak*_*ont 27 c++ language-lawyer c++11 std-function c++14
所有报价均来自N3797.
4/3 [转]
当且仅当声明T t = e时,表达式e可以隐式转换为类型T. 对于一些发明的临时变量t而言,其形式良好
这意味着没有表达式可以隐式转换为void,这void t=e对所有表达式都是非法的e.如果e是类型的表达式void,例如,这甚至是真的void(3).
所以类型的表达式void不能隐式转换为void.
这导致我们:
20.9.2/2要求[func.require]
将INVOKE(f,t1,t2,...,tN,R)定义为隐式转换为R的INVOKE(f,t1,t2,...,tN).
总之,INVOKE(f, t1, t2, ..., tN, R)当是永远有效R的void,如无(含void)可以隐式转换为void.
因此,所有都std::function<void(Args...)>具有属性!*this,因此不能被调用,因为唯一没有!*this后置条件的构造函数(或者不从function相同类型的另一个复制此类状态)需要Callable其中一个参数.
20.9.11.2/7类模板函数[func.wrap.func]
要求:F应为CopyConstructible.对于参数类型ArgTypes,f应为Callable(20.9.11.2)并返回R类型.A的拷贝构造函数和析构函数不应抛出异常.
20.9.11.2/2类模板函数[func.wrap.func]
类型F的可调用对象f对于参数类型ArgTypes是Callable,如果表达式INVOKE(f,declval()...,R)被认为是未评估的操作数(第5条),则返回类型R( 20.9.2).
如上所述,没有Callable表达std::function<void(Args...)>.
如果以某种方式std::function<void(Args...)>找到这样的地方,调用operator()将会形成错误:
调用[func.wrap.func.inv]
效果:INVOKE(f,std :: forward(args)...,R)(20.9.2),其中f是*this的目标对象(20.9.1).
因为INVOKE(f, std::forward<ArgTypes>(args)..., void)所有论据和形式都是错误的f.
这种推理是否合理?
eca*_*mur 16
是的,你的分析是正确的; 我在这里得出了同样的结论.
根据Daniel Kruegler的说法,这个问题应该出现在下一个邮件之后的库缺陷列表中:
已提交相应的库问题,但在问题列表中尚未显示.
希望一旦变得可见,我们也将得到一个结论性的答案:是否允许构造std::function带有签名的返回void传递带有签名的可调用返回非void(使用`std :: function <void(...)>`调用非空函数).
更新:这是作为LWG 2420输入的,它被解析为支持特殊套管void返回类型到static_cast调用函数的结果void.这意味着可调用的返回非void可以是a的目标std::function<void(...)>.LWG2420作为出版后修正应用于C++ 14; 同时,我所知道的所有编译器都有效地将此行为应用为C++ 11模式的扩展.