Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Полезный смысл функции с аргументом &&rvalue против const&lvalue при копировании значения

#cpp #cpp11


Рассмотрим следующий псевдокод:

класс Параметр {
    double значение_;
public:
    Параметр& задать(const double& зн){ значение_=зн; return *this; }
    Параметр& задать(double && зн){ значение_=зн; return *this; }
};


но вернее будет общий случай:

template
класс Параметр {
    T значение_;
public:
    Параметр& задать(const T& зн){ значение_=зн; return *this; }
    Параметр& задать(T && зн)    { значение_=зн; return *this; }
};



В чём может быть профит от использования здесь rvalue? Я понимаю, что так как в любом
случае идёт копирование в rvalue нет никакого смысла.
Покажите, пожалуйста, на примере близком к этому когда же может получится польза.


На (2) пример бы написал такой(благодарю ixSci)

класс Параметр {
    std::string значение_;
public:
    Параметр& задать(const std::string & зн){ значение_=зн; return *this; }
    Параметр& задать(std::string && зн)     { значение_=std::move(зн); return *this; }
};


Получается на сложных объектах это может сэкономить производительность.
    


Ответы

Ответ 1



В первом куске кода ссылки не нужны вообще, так что в обоих примерах их нужно убрать — там лучше обычное копирование, т.к. double. Второй пример — другое дело. Давайте рассмотрим возможные варианты вызова функции задать: задать("тему"). Для такого вызова сначала будет создан временный объект типа std::string, затем, для варианта с const&, будет вызван оператор присваивания, который выделит память, скопирует строку, а потом будет вызван деструктор временного объекта, который удалит временный объект и память, которую он выделял на куче(в случае оптимизации малых строк, никакой памяти не будет, но это оставим за скобками). Во втором варианте никакого копирования не произойдёт, вернее произойдёт копирование указателя, из временного объекта в постоянный.Что гораздо быстрее, чем копирование всей строки(с предварительным выделением памяти), после чего будет так же вызван деструктор временного объекта, который ничего уже не будет делать. Все плюсы перемещающей семантики зависят исключительно от того, как реализован перемещающий конструктор(оператор присваивания). В std::string он реализован так, чтобы он имел преимущества перед копированием. К этому должен стремиться любой класс содержащий ресурсы. В стандартной библиотеке этим преимуществом пользуется все классы, которые могут.

Ответ 2



rvalue-ссылка интресена только для объектов, чей класс предусматривает оптимизорованный продуманный специальный конструктор перемещения. Хорошая STL - хороший пример. На простых типах от неё толку как от обычной ссылки - может сэкономить копирование нескольких маш.слов = sizeof(type)-sizeof(void*). То есть при копировании большого массива double на 32-битной машине даст 2ую экономию. подходит. Благодарю @ixSci. Я перефразировал до краткости по сути вопроса.

Комментариев нет:

Отправить комментарий