Параметры значения неявно перемещаются при возврате по значению? - PullRequest
22 голосов
/ 15 мая 2011

Рассмотрим следующую функцию:

Foo foo(Foo x)
{
    return x;
}

Будет ли return x вызывать конструктор копирования или конструктор перемещения? (Оставим здесь NRVO в стороне.)

Чтобы исследовать, я написал простой Foo класс, который является только подвижным, но не копируемым:

struct Foo
{
    Foo() = default;
    Foo(const Foo&) = delete;
    Foo(Foo&&) = default;
};

Если конструктор перемещения был вызван при возврате параметров-значений по значению, все должно быть в порядке. Но текущий компилятор g ++ жалуется на return x со следующим сообщением об ошибке:

error: deleted function 'Foo::Foo(const Foo&)'

Если я заменю return x на return std::move(x), все в порядке. Из этого я заключаю, что переход от значений параметров должен быть сделан явно, если это необходимо. Соответствует ли поведение g ++ или нет?

Ответы [ 2 ]

24 голосов
/ 15 мая 2011

Если для Foo есть ctor хода, его следует выбрать.

Параметры функции явно исключаются из допустимости копирования в операторах возврата (FDIS §12.9p31, первый маркер):

  • в операторе возврата в функции с типом возврата класса, когда выражение является именем энергонезависимого автоматического объекта (кроме параметра функции или предложения catch)

Однако в следующем параграфе явно возвращаются факторы перемещения:

Если критерии исключения операции копирования выполнены или будет выполнено, за исключением того факта, что исходный объект является параметром функции , а копируемый объект обозначен lvalue, перегрузка Разрешение на выбор конструктора для копии сначала выполняется , как если бы объект был обозначен значением r . ...

(Акцент мой в обеих цитатах.)

12 голосов
/ 15 мая 2011

Это допустимый код - поведение G ++ не соответствует.MSVC10 поддерживает это поведение.

...