Обычная реализация RVO состоит в том, что вызывающий код передает адрес куска памяти, где функция должна создать свой объект результата.
Когда результат функции напрямую является автоматической переменной, которая не является формальным аргументомто, что эта локальная переменная может быть просто помещена в предоставленный вызывающей стороной блок памяти, и оператор return тогда вообще не копирует.
Для аргумента, переданного значением, вызывающий машинный код должен инициализировать его копиюфактический аргумент в расположение формального аргумента перед переходом к функции.Чтобы функция поместила свой результат туда, ей сначала пришлось бы уничтожить объект формального аргумента, что имеет несколько хитрых особых случаев (например, когда эта конструкция прямо или косвенно ссылается на объект формального аргумента).Таким образом, вместо идентификации местоположения результата с помощью формального местоположения аргумента, оптимизация здесь логически должна использовать отдельный вызываемый предоставленный кусок памяти для результата функции.
Однако результат функции, который не передается врегистр обычно предоставляется вызывающим абонентом.То есть то, что можно разумно говорить как RVO, разновидность уменьшенного RVO, для случая выражения return
, которое обозначает формальный аргумент, - это то, что произойдет в любом случае.И он не соответствует тексту «путем создания автоматического объекта непосредственно в возвращаемом значении функции».
Подводя итог, поток данных, требующий, чтобы вызывающий объект передал значение, означает, что он обязательно является вызывающим.который инициализирует хранение формального аргумента, а не функцию.Следовательно, нельзя избежать копирования из формального аргумента в целом (этот термин ласки охватывает особые случаи, когда компилятор может делать совершенно особые вещи, в частности, для встроенного машинного кода).Тем не менее, это функция, которая инициализирует любое другое локальное автоматическое хранилище объектов, и тогда нет проблем с выполнением RVO.