Namespaces
Variants

C++ named requirements: Swappable

From cppreference.net
C++ named requirements

이 타입의 모든 좌측값 또는 우측값은, 비한정 함수 호출 swap ( ) 를 사용하여 다른 타입의 모든 좌측값 또는 우측값과 교환될 수 있습니다. 이는 std::swap 과 사용자 정의 swap ( ) 들이 모두 보이는 컨텍스트에서 수행됩니다.

목차

요구사항

타입 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 가 보유하던 값입니다. 인수 종속 lookup 으로 찾은 해당 이름을 가진 모든 함수와 <algorithm> (C++11 이전) <utility> (C++11 이후) 헤더에 정의된 두 개의 std::swap 템플릿 중에서 오버로드 해결을 통해 찾은 swap ( ) 함수를 호출합니다.
#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으로 전달(forward)할 수 있도록 합니다.
2) 클래스 내에서 friend function 을 정의합니다 (이 접근 방식은 ADL 이외의 이름 검색에서 클래스 특화 swap을 숨깁니다).

참고 사항

표준 라이브러리 함수들이 스왑을 수행할 때 <algorithm> (until C++11) <utility> (since C++11) 가 실제로 포함되는지는 명시되지 않으므로, 사용자 제공 swap ( ) 는 해당 헤더가 포함될 것이라고 기대해서는 안 됩니다.

예제

#include <iostream>
#include <vector>
struct IntVector
{
    std::vector<int> v;
    IntVector& operator=(IntVector) = delete; // 할당 불가
    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); // 컴파일 오류! std::swap은 MoveAssignable을 요구함
    prn();
    std::iter_swap(&v1, &v2); // OK: 라이브러리가 비한정 swap()을 호출함
    prn();
    std::ranges::swap(v1, v2); // OK: 라이브러리가 비한정 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 을 모두 사용하도록 명확히 함

참고 항목

해당 타입의 객체가 동일한 타입이나 다른 타입의 객체와 교환 가능한지 확인합니다
(클래스 템플릿)
타입이 교환 가능하거나 두 타입이 서로 교환 가능함을 명시합니다
(컨셉)