c++ - std::function 赋值应该忽略返回类型吗?

标签 c++ c++11 std-function c++14

<分区>

根据 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 改变了.

关于c++ - std::function 赋值应该忽略返回类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25385876/

相关文章:

c++ - 如何检查分离的 std::thread 是否仍在运行?

c++ - std::function:无法将派生类参数转换为基类参数

c++ - 在 std::function 中捕获 lambda 会产生额外的拷贝

c++ - hash_map 不工作

c++ - 使用 `auto` 作为函数参数是否违反 C++ 标准?

c++ - 将 std::unique_ptr 转换为 std::unique_ptr 到父类(super class)的正确方法是什么?

c++ - 尽管参数是 r 值引用,为什么要使用 std::move

c++从文件中读取以构建基于指针的迷宫

c++ - 如何以几秒的间隔多次使用 QTcpSocket 实例?

c++ - std::function 和 std::bind: 它们是什么,应该在什么时候使用它们?