c++ - 将局部变量绑定(bind)到闭包的最便宜的方法

标签 c++ c++11

我相信以下是将局部变量绑定(bind)到闭包的最便宜的方法:

void ByRValueReference(A&& a) {
}

std::function<void ()> CreateClosureByRValueReference() {
  A a;
  std::function<void ()> f = std::bind(&ByRValueReference, std::move(a)); // !!!
  return f;
}

但是,它不能在 Clang 3.1 下编译:

error: no viable conversion from '__bind<void (*)(A &&), A>' to 'std::function<void ()>'

和 gcc 4.6.1:

/usr/include/c++/4.6/functional:1778:2: error: no match for call to ‘(std::_Bind<void (*(A))(A&&)>) ()’

我是在违反标准还是只是破坏了标准库?

最佳答案

这是 std::bind 的设计。完整规范在 20.8.9.1.2 函数模板绑定(bind) [func.bind.bind] 中,但在这种情况下,第 10 段的最后一个项目符号(描述如何使用绑定(bind)参数)适用:

— otherwise, the value is tid and its type Vi is TiD cv &

所以换句话说,std::move(a) 将导致调用包装器存储一个 A(来自 move 构造),然后当 使用 operator() 该成员将作为左值 转发(附加的 cv 限定符与调用包装器的 cv 限定符相匹配,但我离题了)。即使它作为右值传递。

这种不匹配可以通过 lambda 来解决:

std::bind([](A& a) { ByRValueReference(std::move(a)); }, std::move(a))

这可以说更明确的是,对包装的结果调用的进一步调用是可疑的(因为 A 成员可能已被移走),但我并不过分喜欢std::bind 作为一个整体的行为。

关于c++ - 将局部变量绑定(bind)到闭包的最便宜的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10053998/

相关文章:

c++ - 为什么我的模板需要 C++ 链接?

c++ - 改进折叠功能

c++ - C++ 风格转换对性能的影响?

c++ - 没有匹配函数调用 'fscanf'

c++ - 在 Mac 上编译 C++11 代码?

c++ - 我是否需要知道算法的代码才能利用插入器和移动迭代器?

c++ - 是否有任何理由将 final 说明符与 union 一起使用?

c++ - SFINAE 启用/禁用功能和模板别名

c++ - CMake 中的全程序优化

c++ - 在 IOKit 代码中使用 `decltype`