Spec-Zone.ru › C++

Именованные требования C++: Swappable

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

Требования

Тип U является Swappable с типом T, если для любого объекта u типа U и любого объекта t типа T

Выражение Требования Семантика
#include <algorithm> // until C++11 #include <utility> // since C++11 using std::swap; swap(u, t); После вызова значение t является значением, которое имел u до вызова, а значение u является значением, которое имел t до вызова. Вызывает функцию с именем swap(), найденную разрешением перегрузки среди всех функций с таким именем, обнаруженных посредством поиска, зависящего от аргументов, и двух шаблонов std::swap, определённых в заголовочном файле <algorithm>(до C++11)<utility>(начиная с C++11).
#include <algorithm> // until C++11 #include <utility> // since C++11 using std::swap; swap(t, u); То же То же

Многие функции стандартной библиотеки (например, многие алгоритмы) требуют, чтобы их аргументы удовлетворяли требованиям Swappable, то есть при каждой операции обмена, выполняемой стандартной библиотекой, используется эквивалент using std::swap; swap(t, u);.

Типичные реализации либо

1) Определяют нешаблонную функцию swap в объемлющем пространстве имён, которая может перенаправлять вызов на функцию swap-член, если требуется доступ к закрытым членам данных.
2) Определяют функцию-друг внутри класса (при таком подходе специфичная для класса функция swap скрывается от поиска имён, за исключением ADL).

Примечания

Не указано, включается ли <algorithm>(до C++11)<utility>(начиная с C++11) фактически при выполнении обмена функциями стандартной библиотеки, поэтому функция swap(), предоставленная пользователем, не должна рассчитывать на её включение.

Пример

#include <iostream>
#include <vector>

struct IntVector
{
    std::vector<int> v;

    IntVector& operator=(IntVector) = delete; // not assignable

    void swap(IntVector& other)
    {
        v.swap(other.v);
    }

    void operator()(auto rem, auto term = " ")
    {
        std::cout << rem << "{{";
        for (int n{}; int e : v)
            std::cout << (n++ ? ", " : "") << e;
        std::cout << "}}" << term;
    }
};

void swap(IntVector& v1, IntVector& v2)
{
    v1.swap(v2);
}

int main()
{
    IntVector v1{{1, 1, 1, 1}}, v2{{2222, 2222}};

    auto prn = [&]{ v1("v1", ", "), v2("v2", ";\n"); };

//  std::swap(v1, v2); // Compiler error! std::swap requires MoveAssignable
    prn();
    std::iter_swap(&v1, &v2); // OK: library calls unqualified swap()
    prn();
    std::ranges::swap(v1, v2); // OK: library calls unqualified swap()
    prn();
}

Вывод:

v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};

Отчёты об ошибках

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

DR Применяется к Поведение согласно опубликованной версии Правильное поведение
LWG 226 C++98 не было ясно, как стандартная библиотека использует swap уточнено, что используются как std::, так и найденная посредством ADL функция swap

См. также

is_swappable_withis_swappableis_nothrow_swappable_withis_nothrow_swappable
(C++17)(C++17)(C++17)(C++17)
проверяет, можно ли обменивать объекты типа с объектами того же или другого типа
(шаблон класса)
is_swappable_with_typeis_swappable_typeis_nothrow_swappable_with_typeis_nothrow_swappable_type
(C++26)(C++26)(C++26)(C++26)
проверяет, можно ли обменивать объекты одного отражённого типа с объектами того же или другого отражённого типа
(функция)
swappableswappable_with
(C++20)(C++20)
задаёт требование, что тип может быть обменян или что два типа могут быть обменяны друг с другом
(концепт)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/named_req/Swappable

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API