Re[3]: Про перемещение (на примере кода)
От: rg45 СССР  
Дата: 15.03.25 18:54
Оценка: 8 (1)
Здравствуйте, Shmj, Вы писали:


S>
S>    TrackedClass take() {
S>        return  _trackedClass; // <- тут копия порождается.
S>    }
S>};
S>


Верно.

S>
S>    TrackedClass take() {
S>        TrackedClass tc = std::move(_trackedClass); // <- Копия не порождается.
S>        return tc;
S>    }
S>


Здесь сначала происходит перемещение содержимого объекта _trackedClass в локальный объект tc. И нужно понимать, что время жизни объекта _trackedClass при этом не заканчивается. Скорлупа этого (под)объекта будет жить, пока живет его полный объект. Также примечательно то, что объект tc является move eligible. Это означает, что, если к нему не будет применена NRVO, то к нему будет применено ещё одно перемещение. Т.е. либо NRVO (что скорее всего), либо второе перемещение, копирования точно не будет.

Как бы то ни было, хотя бы одного перемещения здесь не избежать. Поэтому смысла в этом локальном объекте tc нет никакого. Лучше писать просто:

    TrackedClass take() { return std::move(_trackedClass); }

Так и код проще, и потенциальное число перемещений меньше.

S>
S>TrackedClass fun1() {
S>    Wrapper w = Wrapper();
S>    TrackedClass t = w.take(); // <- копия НЕ порождается.
S>    return t;
S>}
S>


Строго говоря, здесь копия может порождаться, а может нет. Стандарт языка не регламентирует число промежуточных копий, это implementation specifics. Но, если NRVO таки было подключено, что скорее всего, тогда никаких дополнительных копий не будет.

К счастью, этот пример можно легко видоизменить так, чтоб вместо необязательной NRVO применялась обязательная RVO:

TrackedClass fun1() {
    Wrapper w = Wrapper();
    return w.take(); // <- копия НЕ порождается СТОПУДОВО!
}


То, что в этом случает не будет промежуточных копий, гарантируется стандартом языка.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 15.03.2025 19:10 rg45 . Предыдущая версия . Еще …
Отредактировано 15.03.2025 19:08 rg45 . Предыдущая версия .
Отредактировано 15.03.2025 19:06 rg45 . Предыдущая версия .
Отредактировано 15.03.2025 18:57 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.