【问题标题】:std::bind(): bind lambda with rvalue reference as argumentstd::bind():以右值引用作为参数绑定 lambda
【发布时间】:2014-10-11 14:18:02
【问题描述】:

我正在使用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&amp; 而不是 Dog&amp;&amp;,代码运行良好并具有预期的输出。当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 将绑定的参数作为左值传递,因此它与右值引用不匹配。

标签: c++ c++11 lambda stdbind


【解决方案1】:

std::bind 的规范相当密集。简而言之,一个普通的绑定参数(不是绑定表达式,不是reference_wrapper,也不是占位符)作为std::forward&lt;Vi&gt;(tid) 传递给绑定函数,其中ViTiD cv &amp;cv 是cv-调用包装器的限定符,TiDdecay_t&lt;Ti&gt; 类型,Ti 是实际传递给 bind 的类型,tid 是“从 std::forward&lt;Ti&gt;(ti) 构造的 TiD 类型的左值”,以及ti 是传递给 bind 的参数。

将此应用于您的电话,我们看到TiDogtiDog("DogABC")。所以TiD 也是Dog,而Vicv Dog &amp;,这意味着std::forward&lt;Vi&gt;(Tid) 是一个左值,编译器会抱怨因为你的lambda 需要一个右值引用参数,并且右值引用参数不能绑定到左值。

【讨论】:

    猜你喜欢
    • 2016-04-24
    • 2015-07-17
    • 1970-01-01
    • 2016-03-14
    • 2015-07-17
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 2015-07-14
    相关资源
    最近更新 更多