c++ - std::bind 和右值引用

标签 c++ c++11 rvalue-reference

让我们考虑以下代码:

class Widget{
};

int main(){
Widget w;
auto lambda = bind([](Widget&& ref){ return; }, std::move(w));

return 0;
}

它会触发错误

no match for call to ‘(std::_Bind<main()::<lambda(Widget&&)>(Widget)>) ()’
     lambda();

我的问题是:为什么会出现错误?毕竟,我对右值引用进行了显式转换——我的意思是 std::move(w)我通过右值引用来论证——我的意思是Widget&& ref .

怎么了?

而且下面的代码有效,让我更担心的是:

class Widget{
};

int main(){
Widget w;
auto lambda = bind([](Widget& ref){ return; }, std::move(w));

return 0;
}

最佳答案

如果您写下 std::bind 的示意性作用,它可能会变得更清楚。

// C++14, you'll have to write a lot of boilerplate code for C++11
template <typename FuncT, typename ArgT>
auto
bind(FuncT&& func, ArgT&& arg)
{
  return
    [
      f = std::forward<FuncT>(func),
      a = std::forward<ArgT>(arg)
    ]() mutable { return f(a); };  // NB: a is an lvalue here
}

由于您可以多次调用 std::bind 给您的函数对象,它不能“用完”捕获的参数,因此它将作为左值引用传递。您向 bind 本身传递一个右值这一事实仅意味着在初始化 a 的行上没有复制。

如果您尝试使用上面显示的原理图 bind 编译您的示例,您还会从编译器中获得更有帮助的错误消息。

main.cxx: In instantiation of ‘bind(FuncT&&, ArgT&&)::<lambda()> mutable [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]’:
main.cxx:10:33:   required from ‘struct bind(FuncT&&, ArgT&&) [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]::<lambda()>’
main.cxx:11:31:   required from ‘auto bind(FuncT&&, ArgT&&) [with FuncT = main()::<lambda(Widget&&)>; ArgT = Widget]’
main.cxx:18:59:   required from here
main.cxx:11:26: error: no match for call to ‘(main()::<lambda(Widget&&)>) (Widget&)’
    ]() mutable { return f(a); };  // NB: a is an lvalue here
                          ^
main.cxx:11:26: note: candidate: void (*)(Widget&&) <conversion>
main.cxx:11:26: note:   conversion of argument 2 would be ill-formed:
main.cxx:11:26: error: cannot bind ‘Widget’ lvalue to ‘Widget&&’
main.cxx:18:33: note: candidate: main()::<lambda(Widget&&)> <near match>
   auto lambda = bind([](Widget&&){ return; }, std::move(w));
                                 ^
main.cxx:18:33: note:   conversion of argument 1 would be ill-formed:
main.cxx:11:26: error: cannot bind ‘Widget’ lvalue to ‘Widget&&’
    ]() mutable { return f(a); };  // NB: a is an lvalue here

关于c++ - std::bind 和右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34877699/

相关文章:

c++ - C++ 中的水平输出值

c++ - 非生成的特殊成员函数与删除的特殊成员函数

c++ - 如何通过 std::unique_ptr 成员调用其他类的 const 成员函数

c++ - 完美转发到作为参数接收的 lambda

c++ - 试图从 zeromq pollitem 获取套接字实例

c++ - Linux 系统调用 getname info 返回 EAI_AGAIN

c++ - `std::enable_if` 是函数指针——怎么样?

c++ - std::forward of rvalue ref to lambda?

c++ - 重载决策中的 const/non-const 右值引用

C++ 编译错误(REPAST 库)