我相信以下是将局部变量绑定(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 typeVi
isTiD 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/