Passing rvalues through std::bind
c++, c++11, rvalue, rvalue-reference, std
Solution
The reason this fails is because when you specify `foo<Movable>`, the function you're binding to is:
void foo(Movable&&) // *must* be an rvalue
{
}
However, the value passed by `std::bind` will not be an rvalue, but an lvalue (stored as a member somewhere in the resulting `bind` functor). That, is the generated functor is akin to:
struct your_bind
{
your_bind(Movable arg0) :
arg0(arg0)
{}
void operator()()
{
foo<int>(arg0); // lvalue!
}
Movable arg0;
};
Constructed as `your_bind(Movable())`. So you can see this fails because `Movable&&` cannot bind to `Movable`.†
A simple solution might be this instead:
auto f = std::bind(foo<Movable&>, Movable());
Because now the function you're calling is:
void foo(Movable& /* conceptually, this was Movable& &&
and collapsed to Movable& */)
{
}
And the call works fine (and, of course, you could make that `foo<const Movable&>` if desired). But an interesting question is if we can get your original bind to work, and we can via:
auto f = std::bind(foo<Movable>,
std::bind(static_cast<Movable&&(&)(Movable&)>(std::move<Movable&>),
Movable()));
That is, we just `std::move` the argument before we make the call, so it can bind. But yikes, that's ugly. The cast is required because `std::move` is an overloaded function, so we have to specify which overload we want by casting to the desired type, eliminating the other options.
It actually wouldn't be so bad if `std::move` wasn't overloaded, as if we had something like:
Movable&& my_special_move(Movable& x)
{
return std::move(x);
}
auto f = std::bind(foo<Movable>, std::bind(my_special_move, Movable()));
Which is much simpler. But unless you have such a function laying around, I think it's clear you probably just want to specify a more explicit template argument.
† This is different than calling the function without an explicit template argument, because explicitly specifying it removes the possibility for it to be deduced. (`T&&`, where `T` is a template parameter, can be deduced to anything, if you let it be.)
Problem
I want to pass an rvalue through `std::bind` to a function that takes an rvalue reference in C++0x. I can't figure out how to do it. For example: ``` #include <utility> #include <functional> template<class Type> void foo(Type &&value) { Type new_object = std::forward<Type>(value); // move-construct if possible } class Movable { public: Movable(Movable &&) = default; Movable &operator=(Movable &&) = default; }; int main() { auto f = std::bind(foo<Movable>, Movable()); f(); // error, but want the same effect as foo(Movable()) } ```