Коротко - незачем)
Но как всегда есть нюансы. Забайтились? Погнали разбираться.
Как всю историю человечества разделяет Рождество Христово, так и история С++ делится на две эпохи появлением стандарта С++11. Получается, что С++11 - Иисус в мире плюсов...
И вот до С++11 мы не имели семантики перемещения и функция std::swap обменивала два значения через копирование. Ну и естественно это никому не нравилось. Зачем такой оверхед, когда мне нужно только местами данные поменять?
И вот в те времена кастомная функция swap была как нельзя кстати. Именно поэтому std::vector имеет отдельный метод swap. Рудимент архаичного прошлого...
С тех пор все стандартные алгоритмы в первую очередь ищут use-defined swap и уже на крайняк используют std::swap.
Если ваш класс управлял хоть каким-то ресурсом, даже строкой, вам нужен был свап.
Но по сути-то, свап - это такой одновременный мув друг в друга(идейно). Ну и с появлением мув-семантики стандратная swap стала выглядеть именно так, как нам нужно идейно:
template <typename T>
void swap(T& x, T& y)
{
T temp(std::move(x));
x = std::move(y);
y = std::move(temp);
}
Эта версия свапа делает ровно то, что ожидали практически от всех кастомных swap'ов - эффективный обмен двух значений.
Она позволяет даже некопируемым объектам, типа стримов, мьютексов и прочих, обменяться местами. То есть она буквально отобрала весь хлеб у кастомной swap: теперь стандратная функция делает такой же эффективный обмен значениями, плюс может также обменять некопируемые объекты. Красота!
Но у самописной swap остается одно преимущество: Не происходит никаких вызовов конструкторов классов обмениваемых объектов. Мы напрямую обмениваем содержимое объектов. А std::swap все-таки вызывает один мув-конструктор и 2 мув присваивания. О производительности надо думать...
А еще надо думать об оптимизациях компилятора. Специальные методы могут быть заинлайнены и std::swap превратится ровно в то же, что сгенерирует компилятор для вашей самописной обменивалки.
Также некоторый легаси код может использовать в своих кишках именно метод swap, поэтому чтобы пользоваться этим кодом, нужно реализовывать метод. Но это не то, что бы частая история.
Итог какой: кастомный своп был придуман, в основном, чтобы эффективно обменивать объекты. std::swap на стероидах мув-семантики позволяет делать это очень эффективно. Самописный своп имеет на первый взгляд незначительные преимущества по производительности. Но на практике как всегда надо тестировать оба варианта. Ну или не заниматься преждевременной оптимизацией и использоват std::swap.
Use standard things. Stay cool.
#cppcore #cpp11