Spec-Zone.ru › C++

C++ named requirements: Swappable

Any lvalue or rvalue of this type can be swapped with any lvalue or rvalue of some other type, using unqualified function call swap() in the context where both std::swap and the user-defined swap()s are visible.

Требования

Тип U является совместимым с типом 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, что означает, что каждый раз, когда стандартная библиотека выполняет операцию swap, она использует эквивалент using std::swap; swap(t, u);.

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

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

Примечания

Не определено, включен ли <algorithm>(до C++11)<utility>(с C++11) в действительности при выполнении операций swap стандартными библиотечными функциями, поэтому пользовательская 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)
проверяет, могут ли объекты типа быть поменяв местами с объектами того же или другого типа
(шаблон класса)
swappableswappable_with
(C++20)
определяет, что тип может быть поменяв местами или что два типа могут быть поменяв местами друг с другом
(концепция)

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

Spec-Zone.ru

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