Namespaces
Variants

std::swap

Материал из ru.cppreference.net
(Перенаправлено с cpp/utility/swap)
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы для диапазонов (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









 
Определён в заголовочном файле <algorithm>
(до C++11)
Определён в заголовочном файле <utility>
(начиная с C++11)
Определён в заголовочном файле <string_view>
template< class T >
void swap( T& a, T& b );
(1) (условно noexcept начиная с C++11)
(constexpr начиная с C++20)
template< class T2, std::size_t N >
void swap( T2 (&a)[N], T2 (&b)[N] );
(2) (условно noexcept начиная с C++11)
(constexpr начиная с C++20)

Обменивает заданные значения.

1) Меняет местами значения a и b.

Эта перегрузка участвует в разрешении перегрузки только если std::is_move_constructible_v<T> && std::is_move_assignable_v<T> является true.

(начиная с C++17)
2) Меняет местами массивы a и b. Эквивалентно std::swap_ranges(a, a + N, b).

Эта перегрузка участвует в разрешении перегрузки только если std::is_swappable_v<T2> является true.

(начиная с C++17)

Параметры

a, b - значения для обмена
Требования к типам
-
T должен удовлетворять требованиям CopyConstructible и CopyAssignable (до C++11) MoveConstructible и MoveAssignable (начиная с C++11) .
-
T2 должен удовлетворять требованиям Swappable .

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

(нет)

Исключения

1)

(нет)

(до C++11)
noexcept спецификация:
(начиная с C++11)
2)
noexcept спецификация:
noexcept ( noexcept ( swap ( * a, * b ) ) )
Поиск идентификатора swap в спецификации исключений находит этот шаблон функции в дополнение к тому, что найдено обычными правилами поиска, делая спецификацию исключений эквивалентной C++17 std::is_nothrow_swappable .
(начиная с C++11)
(до C++17)
noexcept спецификация:
noexcept ( std:: is_nothrow_swappable_v < T2 > )
(начиная с C++17)

Сложность

1) Константа.
2) Линейная по N .

Специализации

std::swap может быть специализирована в пространстве имен std для пользовательских типов, но такие специализации не обнаруживаются с помощью ADL (пространство имен std не является ассоциированным пространством имен для пользовательского типа).

(до C++20)

Ожидаемый способ сделать програмно-определяемый тип заменяемым — предоставить нечленную функцию swap в том же пространстве имен, что и тип: подробности смотрите в Swappable .

Следующие перегрузки уже предоставлены стандартной библиотекой:

специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(шаблон функции)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(функция)
специализирует алгоритм std::swap
(функция)

Пример

#include <algorithm>
#include <iostream>
namespace Ns
{
    class A
    {
        int id {};
        friend void swap(A& lhs, A& rhs)
        {
            std::cout << "swap(" << lhs << ", " << rhs << ")\n";
            std::swap(lhs.id, rhs.id);
        }
        friend std::ostream& operator<<(std::ostream& os, A const& a)
        {
            return os << "A::id=" << a.id;
        }
    public:
        A(int i) : id {i} {}
        A(A const&) = delete;
        A& operator = (A const&) = delete;
    };
}
int main()
{
    int a = 5, b = 3;
    std::cout << a << ' ' << b << '\n';
    std::swap(a, b);
    std::cout << a << ' ' << b << '\n';
    Ns::A p {6}, q {9};
    std::cout << p << ' ' << q << '\n';
//  std::swap(p, q); // ошибка, требования к типу не выполнены
    swap(p, q);      // OK, ADL находит подходящую friend-функцию `swap`
    std::cout << p << ' ' << q << '\n';
}

Вывод:

5 3
3 5
A::id=6 A::id=9
swap(A::id=6, A::id=9)
A::id=9 A::id=6

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 227 C++98 T не требовалось быть CopyConstructible или DefaultConstructible
(временный объект типа T мог быть неконструируемым)
T также требуется
быть CopyConstructible
LWG 809 C++98 массивы не могли быть обменены добавлена перегрузка (2)
LWG 2554 C++11 обмен многомерными массивами никогда не может
быть noexcept из-за проблем поиска имени
исправлено для работы

См. также

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