표준 라이브러리는 std :: swap을 어떻게 구현합니까?
STL에서 스왑 기능은 어떻게 구현됩니까? 다음과 같이 간단합니까?
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1);
t1=t2;
t2=tmp;
}
다른 게시물에서는이 기능을 자신의 수업에 특화시키는 것에 대해 이야기합니다. 왜 이렇게해야합니까? std::swap
기능을 사용할 수없는 이유는 무엇 입니까?
어떻게 std::swap
구현됩니까?
예, 질문에 제시된 구현은 클래식 C ++ 03입니다.
보다 현대적인 (C ++ 11) 구현은 std::swap
다음과 같습니다.
template<typename T> void swap(T& t1, T& t2) {
T temp = std::move(t1); // or T temp(std::move(t1));
t1 = std::move(t2);
t2 = std::move(temp);
}
이는 불필요한 복사본 등을 방지하기 때문에 리소스 관리 측면에서 기존 C ++ 03 구현에 비해 개선 된 것입니다. C ++ 11 std::swap
에서는 유형 T
이 MoveConstructible 및 MoveAssignable이어야 하므로 구현 및 개선이 가능합니다. .
맞춤형 구현을 제공해야하는 이유는 무엇입니까?
swap
특정 유형에 대한 의 사용자 정의 구현 은 일반적으로 구현이 표준 버전보다 더 효율적이거나 구체적 일 때 권장됩니다.
이에 대한 전형적인 예는 복사 및 삭제 비용이 많이 드는 많은 양의 리소스를 클래스에서 관리하는 경우입니다. 대신 사용자 지정 구현은 스왑에 영향을주는 데 필요한 핸들이나 포인터를 간단히 교환 할 수 있습니다.
std::move
C ++ 11 이후부터 이동 가능한 유형 (그리고 유형을 구현) 의 출현으로 여기에있는 많은 원래의 근거가 사라지기 시작했습니다. 그럼에도 불구하고 사용자 정의 스왑이 표준 스왑보다 낫다면 구현하십시오.
일반 코드는 ADL 메커니즘을 적절하게 swap
사용하는 경우 일반적으로 사용자 정의를 사용할 수 있습니다 .
STL에서 스왑 기능은 어떻게 구현됩니까?
어떤 구현? 이것은 하나의 구체적인 라이브러리가 아니라 사양입니다. 내 컴파일러의 표준 라이브러리가 어떻게 작동하는지 의미한다면 어떤 컴파일러인지 알려주거나 코드를 직접 읽으십시오.
다음과 같이 간단합니까?
그것은 본질적으로 C ++ 11 이전의 순진한 버전입니다.
이 특수화되지 않은 구현은 복사를 강제 T = std::vector<SomethingExpensive>
합니다. 예를 들어 코드는 다음과 같이 번역됩니다.
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1); // duplicate t1, making an expensive copy of each element
t1=t2; // discard the original contents of t1,
// and replace them with an expensive duplicate of t2
t2=tmp; // discard the original contents of t2,
// and replace them with an expensive duplicate of tmp
} // implicitly destroy the expensive temporary copy of t1
그래서 두 벡터를 교환하기 위해 우리는 본질적으로 세 개의 . 3 개의 동적 할당과 많은 비용이 많이 드는 개체가 복사되었으며 이러한 작업 중 하나가 발생하여 인수가 불확실한 상태로 남을 수 있습니다.
이것은 명백히 끔찍했기 때문에 값 비싼 컨테이너에 과부하가 제공되었고 자신의 값 비싼 유형에 대한 과부하를 작성하도록 권장되었습니다. std::vector
전문화는 벡터의 내부에 접근했다, 모든 복사하지 않고 두 벡터를 교환 할 수 있습니다 :
template <typename T> void swap(vector<T> &v1, vector<T> &v2) { v1.swap(v2); }
template <typename T> void vector<T>::swap(vector<T>& other) {
swap(this->size_, other.size_); // cheap integer swap of allocated count
swap(this->used_, other.used_); // cheap integer swap of used count
swap(this->data__, other.data_); // cheap pointer swap of data ptr
}
여기에는 비용이 많이 들고 동적 (해제) 할당이없는 복사본이 포함되지 않으며 던지지 않는 것이 보장됩니다.
이제이 전문화의 이유는 vector :: swap이 vector의 내부에 액세스 할 수 있고 복사하지 않고도 안전하고 효율적으로 이동할 수 있기 때문입니다.
왜 내가 [자신의 수업을 위해 전문화]를해야합니까?
Pre-C ++ 11 std::vector
은 스와핑을 효율적이고 예외적으로 안전하게 만들기 위해 다음과 같은 이유 입니다.
C ++ 11 이후로 이동 구성 및 할당을 제공하거나 컴파일러가 정상적인 기본값을 생성 할 수있는 경우에는 그렇지 않습니다.
새로운 일반 스왑 :
template <typename T> void swap(T& t1, T& t2) {
T temp = std::move(t1);
t1 = std::move(t2);
t2 = std::move(temp);
}
이동 생성 / 할당을 사용하여 사용자 정의 구현을 전혀 작성할 필요없이 위의 사용자 정의 벡터 구현과 본질적으로 동일한 동작을 얻을 수 있습니다.
참조 URL : https://stackoverflow.com/questions/25286544/how-does-the-standard-library-implement-stdswap
'IT TIP' 카테고리의 다른 글
"빠른 수정"을위한 Visual Studio 바로 가기 (0) | 2020.12.25 |
---|---|
호스트 Mac OS에서 VirtualBox의 게스트 Linux 시스템으로 폴더 공유 (0) | 2020.12.25 |
ASP.NET Core 1.0 Web API의 간단한 JWT 인증 (0) | 2020.12.25 |
스레드 컨텍스트 전환 오버 헤드를 추정하는 방법은 무엇입니까? (0) | 2020.12.25 |
WCF 서비스에 대한 전역 예외 처리기를 어떻게 만듭니 까? (0) | 2020.12.25 |