根据 C++11 或 C++14 标准,下面的代码是否有效?
#include <functional>
int ReturnInt()
{
return 5;
}
int main( int argc, char **argv )
{
std::function< void () > BoundType = ReturnInt;
return 0;
}
代码可以使用最新的 cygwin 版本的 gcc (4.8.3) 和 clang (4.3.2) 正常编译,但不能使用 Visual Studio 2013、Visual Studio 2013 年 11 月 CTP 或 Visual Studio 14 预览版。如果将 std::function 更改为 boost::function,它也会在所有平台上编译。
我找到了 this其他表明它应该有效的堆栈溢出问题。
该代码在 C++11 中是未定义的行为,在 C++14 中是病式的。 C++14 将此备注 添加到此构造函数的规范中:
Remarks: These constructors shall not participate in overload
resolution unless f
is Callable (20.9.11.2) for argument types
ArgTypes...
and return type R
.
Callable 在 [func.wrap.func]/p2 中定义:
A callable object f
of type F
is Callable for argument types ArgTypes
and return type R
if the expression INVOKE (f, declval<ArgTypes>()..., R)
, considered as an unevaluated operand
(Clause 5), is well formed (20.9.2).
为了使此 INVOKE 格式正确,INVOKE 的返回类型没有 R
必须隐式转换为 R
([func.require]/p2).
在 C++11 中,这些语句位于 Requries 子句下,这意味着由客户端来确保它们正确,如果客户端失败,则任何事情都可能发生,包括编译成功。
这被 LWG 2132 改变了.