Я знаю, что определенный объект создается только как временный объект (это частный объект-член в библиотеке). Иногда этот объект дополнительно инициализируется объединением функций-членов (TempObj().Init("param").Init("other param")
). Я хотел бы включить конструкцию перемещения для другого объекта, используя этот временный экземпляр, и поэтому мне было интересно, было ли что-то неверное в return std::move(*this)
,
struct TempObj
{
TempObj &&Member() { /* do stuff */ return std::move(*this); }
};
struct Foo
{
Foo(TempObj &&obj);
};
// typical usage:
Foo foo(TempObj().Member());
Это функционально эквивалентно этому?
struct TempObj
{
TempObj(TempObj &&other);
TempObj Member() { /* do stuff */ return *this; }
};
Foo foo(TempObj().Member());
С семантикой перемещения вы не хотите (или не должны) возвращать ссылки на r-значения из функций … ссылки на r-значения существуют для «захвата» безымянных значений или адресов памяти. Когда вы возвращаете ссылку на r-значение на объект, который на самом деле является l-значением с точки зрения вызывающей стороны, семантика неверна, и вы создаете возможность для ненужных неожиданностей, возникающих, когда другие используют методы вашего объекта ,
Другими словами, было бы лучше ориентировать ваш код так:
Foo foo(std::move(TempObj().Member()));
и имеют TempObj::Member
просто верните ссылку на l-значение. Это делает движение явным, и нет никаких сюрпризов для тех, кто использует методы вашего объекта.
Наконец, нет, это не функционально или семантически эквивалентно вашему последнему примеру. Там вы на самом деле делаете временный копия объекта, и эта копия будет объектом r-значения (т. е. неименованным объектом в этом сценарии) … поскольку предположение о ссылках r-значения заключается в том, что объект является либо неисчезшим значением, либо объектом, и он может поэтому будьте безвредно изменены функцией, которую вы передаете ей, которая принимает аргумент ссылки на r-значение. С другой стороны, если вы передали копию объекта в функцию, то функция не может изменить оригинал. Он просто изменит указанное временное значение r, на которое указывает ссылка, и при выходе из функции временная копия объекта с значением r будет уничтожена.
Других решений пока нет …