Если я правильно понял, семантика перемещения позволяет перемещать и повторно использовать ресурсы из временных, неназванных объектов. RVO, хотя предшествующая семантика перемещения идет дальше и «крадет» весь объект, чтобы избежать дополнительного вызова конструктора и функции назначения / копирования.
Мне кажется, это немного противоречит интуиции, не будет ли это намного быстрее, проще и понятнее для пользователя, если вызываемый конструктор напрямую использует адрес конечной цели lvalue для непосредственного размещения данных там, где они нужны пользователю?
Я имею в виду, «создать этот объект в этом месте» кажется немного более интуитивным, чем «создать этот объект где-нибудь, а затем скопировать его в нужное место».
Да, это «немного противоречит интуиции». При включенном разрешении копирования также исключаются все побочные эффекты конструктора.
#include <iostream>
struct X {
X() { std::cout << "Construct" << std::endl; }
X(X&&) { std::cout << "Move" << std::endl; }
~X() { std::cout << "Destruct" << std::endl; };
};
X f() { return X(); }
int main()
{
X x(f());
return 0;
}
Скопируйте elision: g ++ -std = c ++ 11 src-test / main.cc
Construct
Destruct
Нет копии elision: g ++ -std = c ++ 11 -fno-elide-constructors src-test / main.cc
Construct
Move
Destruct
Move
Destruct
Destruct
Компилятор, зная аппаратное обеспечение, для которого собирается программа / библиотека, может применять (опционально) разрешение копирования.
Язык C ++ сам по себе не знает аппаратно-зависимых механизмов возврата. Следовательно, невозможно построить по определенному адресу в этом контексте.
Других решений пока нет …