Происходит ли (N) RVO, когда значение копируется в существующий объект?

(N) RVO помогает избежать ненужного копирования и создания временных объектов, когда возвращаемое значение присваивается новой переменной (таким образом избегая конструктора копирования).

Так что-то вроде этого должно быть оптимизировано RVO:

MyObj getMyObj() {
return MyObj();
}

MyObj myobj = getMyObj();

Однако произойдет ли это, когда объект сайта вызова уже существует? (Т.е. в случае, когда = оператор используется вместо конструктора копирования). Я пытался найти литературу по этому поводу, но (N) RVO, кажется, всегда описывается в терминах избегания конструктора копирования. Не уверен, что в этом случае безопасно изменить объект сайта вызова.

MyObj myobj;

//will getMyObj() first create a temporary object and then copy it via the = operator?
myobj = getMyObj();

0

Решение

Нет, RVO не применяется. (N) RVO определяется в стандарте исключительно как выбор конструктора.

Мотивация заключается в том, что если конструктор MyObj() бросает, потом во второй фрагмент кода myobj уже существует и должен продолжать существовать в состоянии, в котором он находился до вызова getMyObj(),

Кроме того, я не думаю, что в целом ясно, как на самом деле будет достигнуто строительство на месте. myobj это уже построенный объект, и только operator= «знает», как заменить любые ресурсы, которые он содержит, другими ресурсами.

Возвращаемое значение getMyObj тем не менее, может быть создан непосредственно, и вызывающий код может получить operator=(MyObj &&) (переместить назначение), если есть. Так что код не обязательно требуется либо создание копии, либо копирование-назначение, но оно требует назначения, которое нельзя исключить.

Если все вписано, и MyObj() не может бросить, и у присваивания нет побочных эффектов, тогда в удачный день компилятор может применить правило «как если» и оптимизировать независимо от конкретных правил (N) RVO!

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]