Понимание rvalue ссылки на возврат - PullRequest
0 голосов
/ 02 июня 2018

Например, у меня есть код, такой как ниже

//g++  5.4.0

#include <iostream>

struct data
{
    int n;
    data()
    {
        std::cout << "data()\n";
    }
    data(const data&)
    {
        std::cout << "data(const data&)\n";
    }
    data(data&&)
    {
        std::cout << "data(data&&)\n";
    }
};

class container
{
    data d;    
public:
    data getData()
    {
        return std::move(d);
    }
};

int main()
{
    container c;
    data result = c.getData();
}

И вывод:

data() 
data(data&&)

Я не понимаю, как это работает.Я не объявил тип возвращаемого значения как data&&, но конструктор перемещения хорошо работает для результата.Да, код std::move(d), но тип возвращаемого значения не data&&.Итак, как это работает?

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Этот ответ изменяется в .

data getData()
{
    return std::move(d);
}

Этот метод перемещает d в его возвращаемое значение.

data x = foo.getData();

, который создает этотx из возвращаемого значения getData.Однако стандарт C ++ поощряет и разрешает эту конструкцию быть elided , если getData возвращает prvalue (тип значения, который соответствует).Elision означает, что идентификатор и срок действия возвращаемого значения и x объединены.Существует только один объект, а не два.

Это позволяет пропускать побочные эффекты, такие как операторы печати в конструкторах перемещения.

Таким образом, d - это объект, из которого перемещен объект, и этот переход непосредственно создает x.

Если вы измените getData на возвращение data&&, то в течение getData движение не выполняется, но выполняется снаружи x.

В возвращаемое значение getData никогда не является объектом, это prvalue, а значения prvalue в больше похожи на инструкции по созданию объектов.В действительности elision больше не является обязательным.

0 голосов
/ 02 июня 2018

Если тип возвращаемого значения установлен на data (как в вашем случае), то возвращаемый объект является prvalue.Если тип возвращаемого значения установлен на data&&, то возвращаемый объект является значением xrvalue.

В любом случае возвращаемый объект является значением rvalue, и будет вызываться конструктор перемещения result.

Смотри также: http://stackoverflow.com/a/10159163/4509057

...