TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #410 6.14K
​​Зачем вообще нужен кастомный swap?

Коротко - незачем)

Но как всегда есть нюансы. Забайтились? Погнали разбираться.

Как всю историю человечества разделяет Рождество Христово, так и история С++ делится на две эпохи появлением стандарта С++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
  • 🔥 24
  • 👍 11
  • ❤ 5
  • 😎 1
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →