c++ - std::bind():以右值引用作为参数绑定(bind) lambda

标签 c++ c++11 lambda stdbind

我正在玩 std::bind 和右值引用,但我仍然不知道它是如何工作的,我有以下代码:

class Dog {
 public:
   Dog(const string &name) : name_(name) {
     cout << "Dog::ctor" << endl;
   }
   string GetName() {
     return name_;
   }

 private:
   string name_;
};

auto bind_fun = bind([](Dog &&d){ cout << d.GetName() << endl; }, Dog("DogABC"));
bind_fun(); 

当注释掉 bind_fun() 时,或者如果 lambda 使用 Dog& 而不是 Dog&&,代码运行正常,输出符合预期。当 bind_fun() 未被注释时,出现以下编译时错误:

test3.cpp:109:3: error: no matching function for call to object of type 'std::__1::__bind<<lambda at test3.cpp:108:17>, Dog>'
  f();
  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1749:9: note: candidate template ignored: substitution failure [with _Args = <>]: implicit instantiation of undefined template
      'std::__1::__bind_return<<lambda at test3.cpp:108:17>, std::__1::tuple<Dog>, std::__1::tuple<>, false>'
        operator()(_Args&& ...__args)
        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1758:9: note: candidate template ignored: substitution failure [with _Args = <>]: implicit instantiation of undefined template
      'std::__1::__bind_return<const <lambda at test3.cpp:108:17>, const std::__1::tuple<Dog>, std::__1::tuple<>, false>'
        operator()(_Args&& ...__args) const
        ^
1 error generated.

我的问题是:

  1. 为什么当 lambda 取右值引用时 bind_fun() 不能被调用(不能编译)?
  2. 这里使用引用和右值引用作为 lambda 的参数有什么区别?

最佳答案

std::bind 的规范比较密集。简而言之,一个普通的绑定(bind)参数(不是绑定(bind)表达式,不是 reference_wrapper,也不是占位符)作为 std::forward<Vi>(tid) 传递给绑定(bind)函数。其中 ViTiD cv & , cv是调用包装器的 cv 限定符,TiD是类型 decay_t<Ti> , Ti是实际传递给 bind 的类型, 和 tid是“TiD 类型的左值,由std::forward<Ti>(ti) 构造”,和ti是传递给 bind 的参数.

将此应用于您的通话,我们看到 TiDogtiDog("DogABC") .所以TiD也是Dog , 和 Vicv Dog & ,这意味着 std::forward<Vi>(Tid)是一个左值,编译器会报错,因为你的 lambda 接受了一个右值引用参数,而右值引用参数不能绑定(bind)到一个左值。

关于c++ - std::bind():以右值引用作为参数绑定(bind) lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26315604/

相关文章:

c# - 如何在表达式树中使用括号

c++ - C语言上 "static const char array"可以包含变量的成员吗

c++ - 如何将 ‘std::chrono::duration<int, std::ratio<2629746l, 1l>>’类型转换为 ‘int’类型?

c++ - 如何找到最小第一个索引的 vector<vector<int>> 的所有索引

c++ - 如何从对象内部的 typedef 获取模板参数类型

c++ - C++ 中带有输入函数的 Lambda auto 给出错误

c++ - 在您的 VS 解决方案中创建的 .libs 如何与另一个项目链接?

c++ - STL 喜欢容器 typedef 快捷方式?

c++ - Socket::close() 和 StreamSocket::shutdown() 之间的区别

c# - 检查是否是 bool 值?在动态 Lambda 中为真