В этом подпункте приведены определения заменяемых типов и выражений. В этих определениях let t обозначает выражение типа T, а let u обозначает выражение типа U.
Объект t является swappable with объектом u тогда и только тогда, когда:
выражения swap(t, u) и swap(u, t) действительны при оценке в контексте, описанном ниже, и
эти выражения имеют следующие эффекты:
объект, на который ссылается, t имеет ценность, первоначально принадлежащую u и
объект, на который ссылается, u имеет первоначальное значение t.
Контекст , в котором swap(t, u) и swap(u, t) оцениваются должен гарантировать , что бинарная функция не-член с именем «своп» выбирается с помощью overload resolution по набору кандидатов , который включает в себя:
два swap шаблона функций, определенные в <utility> и
поисковый набор, созданный argument-dependent lookup.
[ Note: Если T и U являются как фундаментальными типами, так и массивами фундаментальных типов и объявления из заголовка <utility> находятся в области видимости, общий поисковый набор, описанный выше, эквивалентен поиску по квалифицированному имени, применяемому к выражению std::swap(t, u) или по std::swap(u, t) мере необходимости. ] — end note
[ Note: Не указано, включает ли компонент библиотеки, требующий замены, заголовок, <utility> чтобы гарантировать соответствующий контекст оценки. ] — end note
Rvalue или lvalue t есть swappable тогда и только тогда, когда их t можно заменить любым rvalue или lvalue, соответственно, типа T.
Тип X удовлетворяющего любой из iterator requirements удовлетворяют требования , ValueSwappable если для любого объекта разыменовываемого x типа X, *x является заменой.
[ Example: Код пользователя может гарантировать, что оценка swap вызовов выполняется в соответствующем контексте при различных следующих условиях:
#include <utility> // Requires: std::forward<T>(t) shall be swappable with std::forward<U>(u). template <class T, class U> void value_swap(T&& t, U&& u) { using std::swap; swap(std::forward<T>(t), std::forward<U>(u)); // OK: uses “swappable with” conditions // for rvalues and lvalues } // Requires: lvalues of T shall be swappable. template <class T> void lv_swap(T& t1, T& t2) { using std::swap; swap(t1, t2); // OK: uses swappable conditions for } // lvalues of type T namespace N { struct A { int m; }; struct Proxy { A* a; }; Proxy proxy(A& a) { return Proxy{ &a }; } void swap(A& x, Proxy p) { std::swap(x.m, p.a->m); // OK: uses context equivalent to swappable // conditions for fundamental types } void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint } int main() { int i = 1, j = 2; lv_swap(i, j); assert(i == 2 && j == 1); N::A a1 = { 5 }, a2 = { -5 }; value_swap(a1, proxy(a2)); assert(a1.m == -5 && a2.m == 5); }
— end example ]