I'm not sure what workaround you'd like here. Assuming you cannot change the call expression of the function object and the target signature, you can wrap the rvalue reference and pass the wrapped object (a temporary) via const ref.
Essentially, the call expands to: f( wrap(move(o)) );
I suspect there's a problem with perfect forwarding, because binding i = bind(&f);
does not work; therefore I've introduced an intermediate step performing perfect forwarding, such that the call is resolved to: f( move( (Object&)wrap( move(o) ) ) );
#include <iostream>
#include <functional>
using namespace std;
struct Object { int m; };
// target function with fixed signature (assuming we cannot change that)
void f(Object&& p) { p.m = 42; std::cout << p.m; };
// was surprised I didn't find any method to chain functions in the StdLib
// so here's my own:
template < typename F1, typename F2, typename P1 >
auto chain2(F1 f1, F2 f2, P1&& p1)
-> decltype( f1(f2( std::forward<P1>(p1) )) )
{
return f1( f2( std::forward<P1>(p1) ) );
}
// a special bind version; mostly syntactic sugar
// note you can also deduce the first template parameter; would be more work
// and not necessary here
template < typename P1, typename F1, typename F2 >
auto bind_chain(F1 f1, F2 f2)
-> decltype( std::bind( &chain2<F1,F2,P1>, f1, f2, std::placeholders::_1 ) )
{
return std::bind( &chain2<F1,F2,P1>, f1, f2, std::placeholders::_1 );
}
// as `std::move` is overloaded, we make things a little bit simpler;
// we later will need to get a function pointer on this, that's why
// I'd like to avoid too much overloading
template < typename T >
// for a certain reason, cannot use && here --------v, clang++3.2 accepts it
typename std::remove_reference<T>::type && my_move(T& p)
{
return std::move(p);
}
struct wrapper
{
Object&& m;
wrapper(Object&& p) : m(std::move(p)) {}
operator Object&() const { return m; }
// alternatively:
// operator Object&&() const { return std::move(m); }
};
int main()
{
Object o;
// we'll need to call the functor with an const ref
function<void(wrapper const&)> i;
// chaining the conversion to rvalue ref with the target function
i = bind_chain<wrapper const&>( &f, &my_move<Object> );
i( move(o) );
return 0;
}