Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rvalue reference usage within initialization lists

I've been playing with Rvalue references lately and I've been experiencing a strange issue. Let's define some simple class named Foo that contains a vector< int >:

class Foo
{
public:

    Foo(std::vector< int >&& v)
        : v_(v)
    {}

private:

    std::vector< int > v_;
};

A Foo instance can be constructed by passing a vector< int > temporary like this:

std::vector< int > temp;
Foo(std::move(temp));

Now, when I tried to step through this code, I noticed that the vector inside Foo is constructed using the copy-constructor instead of the move-constructor. However, if I specify the constructor this way instead:

Foo(std::vector< int >&& v)
    : v_(std::move(v))
{}

Then, the move-constructor of the v_ member is appropriately called. Why is that so? Why is the redundant std::move(v) necessary in the initialization list? Why is the compiler unable to deduce the intent to call the vector move-constructor since the corresponding Foo constructor argument is specified as a Rvalue reference?

By the way, I'm using GCC 4.6 with the -std=c++0x option.

Thanks for your help. PMJ

like image 480
pmjobin Avatar asked Aug 23 '11 18:08

pmjobin


1 Answers

Inside the function (or constructor) a named parameter is an lvalue, even if it is declared as an rvalue reference.

The rationale is something like

void foo(std::vector< int >&& v)
{
   bar(v);
   baz(v);
   boo(v);
   buz(v);
}

In which of these calls should the compiler consider moving from the object v?

None of them, unless you do it explicitly.

like image 124
Bo Persson Avatar answered Nov 30 '22 17:11

Bo Persson