Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::bind and rvalue reference

Let's consider the following piece of code:

class Widget{
};

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

return 0;
}

and it triggers error

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

And my question is: Why the error has appeared? After all, I do an explicit cast to rvalue reference – I mean std::move(w) and I take argument by rvalue reference – I mean Widget&& ref.

What's up?

Moreover the the below code works, what makes me worried the more:

class Widget{
};

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

return 0;
}
like image 448
Gilgamesz Avatar asked Jan 19 '16 13:01

Gilgamesz


People also ask

Can lvalue bind to rvalue reference?

An lvalue reference can bind to an lvalue, but not to an rvalue.

What is the use of std :: bind?

std::bind is a Standard Function Objects that acts as a Functional Adaptor i.e. it takes a function as input and returns a new function Object as an output with with one or more of the arguments of passed function bound or rearranged.

What is the return type of std :: bind?

std::bind return type The return type of std::bind holds a member object of type std::decay<F>::type constructed from std::forward<F>(f), and one object per each of args... , of type std::decay<Arg_i>::type, similarly constructed from std::forward<Arg_i>(arg_i).

What is the difference between lvalue and rvalue references?

“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.


1 Answers

To make it work you need to write it like this:

#include <functional>
#include <iostream>

class Widget{};

int main()
{
    Widget a;
    auto lf = [](Widget&& par){ };

    auto f = std::bind
    (
        lf,
        std::bind
        (
            std::move<Widget&>, a
        )
    );
    f();
    return 0;
}

My compiler is gcc version 4.9.2 20141101 (Red Hat 4.9.2-1) (GCC)

like image 109
neshkeev Avatar answered Sep 22 '22 01:09

neshkeev