Информация об изменениях

Сообщение Re[4]: Про перемещение (на примере кода) от 15.03.2025 19:35

Изменено 15.03.2025 19:39 rg45

Re[4]: Про перемещение (на примере кода)
Здравствуйте, rg45, Вы писали:

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


А раз уж хотя бы одного перемещения не избежать ни при каких раскладах, твоя функция-член take може спокойнеко возвращать rvalue ссылку. И перемешение в этом случае будет происходить не в take, а в fun1:

TrackedClass&& take() {
    return std::move(_trackedClass); // Ни копии, ни перемещения - просто возврат rvalue ссылки.
}

TrackedClass fun1() {
    Wrapper w = Wrapper();
    return w.take(); // То самое одно незибежное перемещение.
}


Но признаться, меня несколько напрягает такой дизайн. Вот нафига вот это безусловное встраивание move внутрь каждого неконстантного объекта? Не лучше ли просто обеспечить оптимальный доступ к члену класса в зависимости от категории выражения, а вызвающий метод уже пускай сам делает move, если захочет:

class Wrapper {
// . . .    
    const TrackedClass& get() const & { return _trackedClass; }
    TrackedClass& get() & { return _trackedClass; }
    TrackedClass&& get() && { return std::move(_trackedClass); }
};

TrackedClass fun1() {
    Wrapper w = Wrapper();
    return std::move(w.get()); // Клиент заказывает перемещение явно. И это хорошо!
}


И опять же, можно проще:

TrackedClass fun1() {
    return Wrapper().get(); // Перемещение автоматом, поскольку объект враппера временный.
}
Re[4]: Про перемещение (на примере кода)
Здравствуйте, rg45, Вы писали:

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


А раз уж хотя бы одного перемещения не избежать ни при каких раскладах, твоя функция-член take може спокойнеко возвращать rvalue ссылку. И перемешение в этом случае будет происходить не в take, а в fun1:

TrackedClass&& take() {
    return std::move(_trackedClass); // Ни копии, ни перемещения - просто возврат rvalue ссылки.
}

TrackedClass fun1() {
    Wrapper w = Wrapper();
    return w.take(); // То самое одно незибежное перемещение.
}


Но признаться, меня несколько напрягает такой дизайн. Вот нафига вот это безусловное встраивание move внутрь каждого неконстантного объекта? Не лучше ли просто обеспечить оптимальный доступ к члену класса в зависимости от категории выражения, а вызвающий метод уже пускай сам делает move, если захочет:

class Wrapper {
// . . .    
    const TrackedClass& get() const & { return _trackedClass; }
    TrackedClass& get() & { return _trackedClass; }
    TrackedClass&& get() && { return std::move(_trackedClass); }
};

TrackedClass fun1() {
    Wrapper w = Wrapper();
    return std::move(w.get()); // Клиент заказывает перемещение явно. И это хорошо!
}


И опять же, можно проще:

TrackedClass fun1() {
    return Wrapper().get(); // Перемещение автоматом, поскольку объект враппера временный.
}


А вот в таком варианте будет копирование:
TrackedClass fun1() {
    Wrapper w = Wrapper();
    return w.get(); // Копирование. Поскольку о перемещении никто не просил.
}