Namespaces
Variants

std::ranges::swap_ranges, std::ranges::swap_ranges_result

С сайта ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Последовательные операции без изменения    
Групповые операции
(C++17)
Операции поиска
Операции изменения последовательности
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разбиения
(C++11)    

Операции сортировки
Операции бинарного поиска
(на разбитых диапазонах)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановки


Политики выполнения (C++17)
(только для пояснения*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Ограниченные алгоритмы
Все имена в этом меню принадлежат пространству имён std::ranges
Последовательные операции без изменения
Операции изменения последовательности
Операции разбиения
Операции сортировки
Операции бинарного поиска (на отсортированных диапазонах)
       
       
Операции над множествами (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
       
       
Операции перестановки
Операции свёртки
Операции над неинициализированной памятью
Типы возврата
 
Определено в заголовке <algorithm>
Сигнатура вызова
template< std::input_iterator I1, std::sentinel_for<I1> S1,
          std::input_iterator I2, std::sentinel_for<I2> S2 >
requires std::indirectly_swappable<I1, I2>
constexpr swap_ranges_result<I1, I2>
    swap_ranges( I1 first1, S1 last1, I2 first2, S2 last2 );
(1) (начиная с C++20)
template< ranges::input_range R1, ranges::input_range R2 >
requires std::indirectly_swappable<ranges::iterator_t<R1>, ranges::iterator_t<R2>>
constexpr swap_ranges_result<ranges::borrowed_iterator_t<R1>,
                             ranges::borrowed_iterator_t<R2>>
    swap_ranges( R1&& r1, R2&& r2 );
(2) (начиная с C++20)
Вспомогательные типы
template< class I1, class I2 >
using swap_ranges_result = ranges::in_in_result<I1, I2>;
(3) (начиная с C++20)
1) Обменивает элементы между первым диапазоном [first1, first1 + M) и вторым диапазоном [first2, first2 + M) через ranges::iter_swap(first1 + i, first2 + i), где M = ranges::min(ranges::distance(first1, last1), ranges::distance(first2, last2)).
Диапазоны [first1, last1) и [first2, last2) не должны перекрываться.
2) Аналогично (1), но использует r1 в качестве первого диапазона и r2 в качестве второго диапазона, как если бы ranges::begin(r1) использовалось как first1, ranges::end(r1) как last1, ranges::begin(r2) как first2 и ranges::end(r2) как last2.

Функциональные объекты, описанные на этой странице, являются объектами функций алгоритмов (неофициально известные как niebloids), то есть:

Параметры

first1, last1 - пара итератор-страж, определяющая первый диапазон элементов для обмена
first2, last2 - пара итератор-страж, определяющая второй диапазон элементов для обмена
r1 - первый диапазон элементов для обмена
r2 - второй диапазон элементов для обмена

Возвращаемое значение

{ first1 + M, first2 + M } .

Сложность

Ровно M обменов.

Примечания

Реализации (например, MSVC STL ) могут использовать векторизацию, когда тип итератора моделирует contiguous_iterator и обмен его типа значений не вызывает ни нетривиальные специальные функции-члены, ни ADL -найденную функцию swap .

Возможная реализация

struct swap_ranges_fn
{
    template<std::input_iterator I1, std::sentinel_for<I1> S1,
             std::input_iterator I2, std::sentinel_for<I2> S2>
    requires std::indirectly_swappable<I1, I2>
    constexpr ranges::swap_ranges_result<I1, I2>
        operator()(I1 first1, S1 last1, I2 first2, S2 last2) const
    {
        for (; !(first1 == last1 or first2 == last2); ++first1, ++first2)
            ranges::iter_swap(first1, first2);
        return {std::move(first1), std::move(first2)};
    }
    template<ranges::input_range R1, ranges::input_range R2>
    requires std::indirectly_swappable<ranges::iterator_t<R1>, ranges::iterator_t<R2>>
    constexpr ranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>,
                                         ranges::borrowed_iterator_t<R2>>
        operator()(R1&& r1, R2&& r2) const
    {
        return (*this)(ranges::begin(r1), ranges::end(r1),
                       ranges::begin(r2), ranges::end(r2));
    }
};
inline constexpr swap_ranges_fn swap_ranges {};

Пример

#include <algorithm>
#include <iostream>
#include <list>
#include <string_view>
#include <vector>
auto print(std::string_view name, auto const& seq, std::string_view term = "\n")
{
    std::cout << name << " : ";
    for (const auto& elem : seq)
        std::cout << elem << ' ';
    std::cout << term;
}
int main()
{
    std::vector<char> p {'A', 'B', 'C', 'D', 'E'};
    std::list<char> q {'1', '2', '3', '4', '5', '6'};
    print("p", p);
    print("q", q, "\n\n");
    // обменять p[0, 2) и q[1, 3):
    std::ranges::swap_ranges(p.begin(),
                             p.begin() + 4,
                             std::ranges::next(q.begin(), 1),
                             std::ranges::next(q.begin(), 3));
    print("p", p);
    print("q", q, "\n\n");
    // обменять p[0, 5) и q[0, 5):
    std::ranges::swap_ranges(p, q);
    print("p", p);
    print("q", q);
}

Вывод:

p : A B C D E
q : 1 2 3 4 5 6
p : 2 3 C D E
q : 1 A B 4 5 6
p : 1 A B 4 5
q : 2 3 C D E 6

Смотрите также

(C++20)
обменивает значения, на которые ссылаются два разыменовываемых объекта
(объект точки настройки)
обменивает значения двух объектов
(объект точки настройки)
обменивает два диапазона элементов
(шаблон функции)
обменивает элементы, на которые указывают два итератора
(шаблон функции)
обменивает значения двух объектов
(шаблон функции)