std::ranges::swap
ko.cppreference.net 한국어판
| 헤더 <concepts>
|
||
namespace ranges {
inline namespace /* unspecified */ {
inline constexpr /* unspecified */ swap = /* unspecified */;
}
}
|
(C++20부터) (커스터마이제이션 포인트 객체) |
|
| 호출 시그니처 |
||
template< class T, class U >
constexpr void ranges::swap( T&& t, U&& u ) noexcept(/* see below */);
|
(C++20부터) | |
t과 u이 참조하는 값을 교환합니다.
ranges::swap(t, u)은 다음 중 하나에 대해 표현식-동등합니다:
(void)swap(t, u), 만약t또는u이 클래스 또는 열거형 타입을 가지고, 그 표현식이 유효하며, 오버로드 결정이 네임스페이스std::ranges내에서 추가 후보template<class T> void swap(T&, T&) = delete;와 함께 수행되는 경우.- 만약 오버로드 결정으로 선택된 함수가
t과u이 참조하는 값을 교환하지 않는다면, 프로그램의 형식이 잘못되었습니다 (진단이 필요하지 않음).
- 만약 오버로드 결정으로 선택된 함수가
- 그렇지 않으면,
(void)ranges::swap_ranges(t, u), 만약t과u이 동일한 크기의 (그러나 요소 타입은 다를 수 있는) lvalue 배열이고ranges::swap(*t, *u)이 유효한 표현식이며, 단noexcept((void)ranges::swap_ranges(t, u))이noexcept(ranges::swap(*t, *u))와 동일한 경우. - 그렇지 않으면,
t과u이 모두V를 모델링하는 동일한 타입std::move_constructible<V>의 lvalue이고std::assignable_from<V&, V>인 경우, 참조된 값을 교환하는 표현식.- 그 표현식에
noexcept연산자를 적용한 결과는std::is_nothrow_move_constructible_v<V> && std::is_nothrow_move_assignable_v<V>와 같습니다. - 그 표현식은 다음 조건이 모두 참일 때 상수 표현식입니다:
V이 LiteralType이고,t = std::move(u))과u = std::move(t)이 모두 상수 부분 표현식이며,- 다음 선언의 초기화자에 있는 전체 표현식이 상수 부분 표현식입니다:
V v1(std::move(t));V v2(std::move(u));
- 그 표현식에
- 그렇지 않으면,
ranges::swap(t, u)의 형식이 잘못되었으며, 이는 치환 실패를 초래할 수 있습니다 (ranges::swap(t, u)이 템플릿 인스턴스화의 즉시 문맥에 나타날 때).
커스터마이제이션 포인트 객체
ranges::swap
이름은
커스터마이제이션 포인트 객체
를 나타내며, 이는
함수 객체
의 const
리터럴
semiregular
클래스 타입입니다. 자세한 내용은
CustomizationPointObject
를 참조하십시오.
예제
이 코드 실행
#include <array> #include <concepts> #include <iostream> #include <ranges> #include <string_view> #include <vector> void print(std::string_view name, std::ranges::common_range auto const& p, std::ranges::common_range auto const& q) { std::cout << name << "1{ "; for (auto const& i : p) std::cout << i << ' '; std::cout << "}, " << name << "2{ "; for (auto const& i : q) std::cout << i << ' '; std::cout << "}\n"; } void print(std::string_view name, int p, int q) { std::cout << name << "1 = " << p << ", " << name << "2 = " << q << '\n'; } struct IntLike { int v; }; void swap(IntLike& lhs, int& rhs) { std::swap(lhs.v, rhs); } void swap(int& lhs, IntLike& rhs) { std::swap(lhs, rhs.v); } std::ostream& operator<<(std::ostream& out, IntLike i) { return out << i.v; } int main() { std::vector a1{10, 11, 12}, a2{13, 14}; std::ranges::swap(a1, a2); print("a", a1, a2); std::array b1{15, 16, 17}, b2{18, 19, 20}; std::ranges::swap(b1, b2); print("b", b1, b2); // std::array c1{1, 2, 3}; std::array c2{4, 5}; // std::ranges::swap(c1, c2); // 오류: ADL에 의해 swap을 찾을 수 없음 int d1[]{21, 22, 23}, d2[]{24, 25, 26}; std::ranges::swap(d1, d2); print("d", d1, d2); // int e1[]{1, 2, 3}, e2[]{4, 5}; // std::ranges::swap(e1, e2); // 오류: 크기가 일치하지 않음 // char f1[]{1, 2, 3}; // int f2[]{4, 5, 6}; // std::ranges::swap(f1, f2); // 오류: ADL에 의해 swap(*f1, *f2)을 찾을 수 없음 IntLike g1[]{1, 2, 3}; int g2[]{4, 5, 6}; std::ranges::swap(g1, g2); // 이종(heterogeneous) swap 지원 print("g", g1, g2); int h1{27}, h2{28}; std::ranges::swap(h1, h2); print("h", h1, h2); }
출력:
a1{ 13 14 }, a2{ 10 11 12 }
b1{ 18 19 20 }, b2{ 15 16 17 }
d1{ 24 25 26 }, d2{ 21 22 23 }
g1{ 4 5 6 }, g2{ 1 2 3 }
h1 = 28, h2 = 27
참고 항목
|
(C++20)
|
타입이 교환 가능하거나 두 타입이 서로 교환 가능함을 명시
(concept) |
|
두 객체의 값을 교환
(function template) |