Rvalue использование ссылки в списках инициализации - PullRequest
7 голосов
/ 23 августа 2011

В последнее время я играю со ссылками на Rvalue, и у меня возникла странная проблема.Давайте определим некоторый простой класс с именем Foo, который содержит vector< int >:

class Foo
{
public:

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

private:

    std::vector< int > v_;
};

Foo Экземпляр может быть создан путем передачи временного vector< int > следующим образом:

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

Теперь, когда я попытался пройти по этому коду, я заметил, что вектор внутри Foo создается с использованием конструктора копирования вместо конструктора перемещения.Однако, если я вместо этого укажу конструктор следующим образом:

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

Затем, соответствующим образом вызывается конструктор перемещения члена v_.Почему это так?Почему избыточный std::move(v) необходим в списке инициализации?Почему компилятор не может определить намерение вызвать вектор-конструктор перемещения, так как соответствующий аргумент конструктора Foo указан как ссылка Rvalue?

Кстати, я использую GCC 4.6 с -std = c ++ 0x option.

Спасибо за вашу помощь.PMJ

1 Ответ

7 голосов
/ 23 августа 2011

Внутри функции (или конструктора) именованный параметр является lvalue, даже если он объявлен как ссылка на rvalue.

Обоснованием является что-то вроде

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

В каком изэти вызовы должен компилятор рассмотреть перемещение от объекта v?

Ни один из них, если вы не сделаете это явно.

...