Не изменяются ли значения параметров при возврате значения?
Рассмотрим следующую функцию:
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++ или нет?
Ответы
Ответ 1
Если есть перемещение ctor для Foo, оно должно быть выбрано.
Функциональные параметры явно исключены из выражения копирования в операторах возврата (FDIS §12.9p31, первая марка):
- в операторе return в функции с возвращаемым типом класса, когда выражение является именем энергонезависимого автоматического объекта (кроме параметра функции или catch-clause)
Однако в следующем параграфе явно приводятся соображения перемещения ctors:
Когда выполняются критерии для выполнения операции копирования или , за исключением того факта, что исходный объект является параметром функции, а подлежащий копированию объект обозначается lvalue, разрешение перегрузки для выбора конструктора для копии сначала выполняется , как если бы объект был обозначен rvalue....
(Акцент мой в обоих кавычках.)
Ответ 2
Это допустимое поведение кода-g++ является несоответствующим. MSVC10 поддерживает это поведение.