Daily bit(e) C++. std::iter_swap
Добавлено 22 июля 2026 в 21:13
Daily bit(e) C++ 39, обмен значениями за итераторами и другими косвенными типами с помощью std::iter_swap.

std::iter_swap – это удобная сокращенная запись для косвенного обмена значениями, т.е. обмена значениями, на которые указывают два итератора.
Хотя оригинальная версия std::iter_swap предназначена только для итераторов, версия для C++20 std::ranges::iter_swap может работать с любым косвенно перемещаемым типом и поддерживает кастомизацию через ADL.
#include <vector>
#include <memory>
#include <ranges>
template <std::bidirectional_iterator It,
std::sentinel_for<It> Sentinel>
void reverse(It begin, Sentinel end)
{
while (begin != end)
{
end = std::prev(end);
if (end == begin)
break;
// использование iter_swap для обмена значениями за итераторами
std::iter_swap(begin,end);
begin = std::next(begin);
}
}
std::vector<int> data{1,2,3,4,5};
reverse(data.begin(), data.end());
// data == {5, 4, 3, 2, 1}
reverse(data.begin()+1, data.end()-1);
// data == {5, 2, 3, 4, 1}
// C++20 ranges
auto a = std::make_unique<int>(7);
auto b = std::make_unique<int>(42);
// версия iter_swap диапазонов работает для любого косвенно перемещаемого типа
std::ranges::iter_swap(a,b);
// *a == 42, *b == 7
struct Indirect
{
int* value_;
// кастомизация iter_swap скрытой дружественной функции
friend void iter_swap(Indirect& l, Indirect& r)
{
int tmp = *l.value_;
*l.value_ = *r.value_;
*r.value_ = tmp;
}
};
int x = 10, y = 20;
Indirect xi(&x), yi(&y);
// вызывает кастомизацию iter_swap для Indirect
std::ranges::iter_swap(xi,yi);
// x == 20, y == 10
