5

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

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&&)>) ()’

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

4

1 回答 1

3

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

— 否则,值为 is tid,其类型ViTiD cv &

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

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

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

这可以说是更明确的是,对结果调用的进一步调用是可疑的(因为该A成员很可能已被移出),但我并不太喜欢std::bind整体的行为。

于 2012-04-07T11:38:16.980 回答