Daily bit(e) C++. std::iter_swap

Добавлено 22 июля 2026 в 21:13

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

Daily bit(e) C++

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

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++ИтераторПрограммирование