2

I would like to create a std::function bound to a member function taking a rvalue argument. Here is my attempt which does not compile ("xxfunction(154): error C2664: ... You cannot bind an lvalue to an rvalue reference" among others).

    class C
    {
    public:
        void F(std::string &&s)
        {
                //do something with s
        }
        C(){}
    };
    C c;
    std::function<void(std::string&&)> pF = std::bind(&C::F,&c,std::placeholders::_1);
    //somewhere far far away
    pF(std::string("test"));

I did some reading and I think it has to do with std::function no using perfect forwarding but I cant figure out how to get it to work.

Edit:

std::function<void(std::string&)> pF = [&c](std::string&in){c.F(std::move(in));};

This is a semi viable work around but it is not perfect because calling pF will work with an lvalue now and move it anyway.

std::string s("test");
pF(s);
auto other = s; //oops
odinthenerd
  • 5,422
  • 1
  • 32
  • 61
  • Your code without changing compiled well by GCC - http://liveworkspace.org/code/49qBgA$3 - maybe it's bug/feature of your compiler ? – borisbn Jan 30 '13 at 14:40
  • clang 3.0 and gcc 4.7.2 both compile your code without complaining, this might be MSVC-specific. Which version are you using? – us2012 Jan 30 '13 at 14:41
  • Why did you use l-value refs in your lambda? – Arne Mertz Jan 30 '13 at 14:47
  • @ArneMertz because with Rvalue refs I get the same errors as with bind – odinthenerd Jan 30 '13 at 14:48
  • MSVC10 is not fully standard-compliant wrt r-value refs and lambdas and `std::function` implementation. So I guess there's nothing you can do but upgrade. – Arne Mertz Jan 30 '13 at 14:53

1 Answers1

0

It seems your std::bind implementation does not support perfect forwarding via placeholders, but since you have C++11 and std::bind is ugly anyways, use lambdas:

std::function<void(std::string&&)> pF 
  = [&c](std::string&& str)
{ 
  c.F(std::move(str)); 
};

Edit:

Note: Although accepted, this answer is not a solution to the problem at hand, because it is not std::bind but MSVC10's std::function implementation that is flawed. However, the suggestion has led to a workaround and therefore was accepted by PorkyBrain.

Community
  • 1
  • 1
Arne Mertz
  • 24,171
  • 3
  • 51
  • 90