2016-11-10 5 views
4

C++ 표준 라이브러리의 모든 종류의 클래스에는 std::basic_ios<CharT>과 같은 일부 다형성 클래스를 비롯하여 멤버 스왑 함수가 있습니다. 템플릿 클래스 std::shared_future<T>은 명확하게 값 유형이고 std::future<T>은 이동 전용 값 유형입니다. 특별한 이유가 있습니까? 그들은 swap() 멤버 함수를 제공하지 않습니다?std :: future <T> 및 std :: shared_future <T>이 (가) 멤버 스왑()을 제공하지 않는 이유는 무엇입니까?

답변

4

멤버 스왑은 C++ 11에서 std::move 지원 이전에 엄청난 성능 향상을 보였습니다. 예를 들어, 하나의 벡터를 다른 지점으로 이동할 수있는 방법이었습니다. vector에서도 사용되었으므로 벡터 벡터에 삽입하면 성능이 완전히 저하되지 않습니다.

template<class T> 
void swap(T& lhs, T& rhs) { 
    auto tmp = std::move(rhs); 
    rhs = std::move(lhs); 
    lhs = std::move(tmp); 
} 

는 기본적으로 빠른 사용자 정의 작성 하나가 될 것입니다 : std::move

많은 때때로 빈 유형, std::swap의 기본 구현을 C++ (11)에 도착했다.

swap의 기존 유형은 (적어도 즉시) 잃어 버릴 가능성이 적습니다. 그러나 새로운 유형의 API를 확장하는 것은 정당화되어야합니다.

기본적으로 이 std::unique_ptr<future_impl> 주위의 래퍼 인 경우 위의 예에서는 4 개의 포인터 읽기, 3 개의 포인터 쓰기 및 하나의 분기가 필요합니다. 그리고 그것을 인라인화한 최적화 컴파일러 은 최적화 된 .swap 멤버 함수가 수행 할 수있는 2 포인터 읽기 및 2 포인터 쓰기 (예 : SSA 사용)로 줄일 수 있습니다.


1는 그래서 결코, 따라서 tmp의 존재가 제거 될 수 발생하지 않는 lhsrhs의 중간 접속을 알고 같은-경우가 증명되면 tmp가 비어 따라서 노 연산 dtor 있습니다.

Static single assignment 여기서 모든 프리미티브 할당은 메타 데이터가 포함 된 새로운 변수를 만듭니다. 그런 다음 해당 변수에 대한 속성을 증명하고 중복 된 변수를 제거합니다.

+0

왜 자격이없는 'swap'에 대한 친구 기능이 아닌 회원 기능입니까? 나는 gcc (4.8)가'unique_ptr'을 최적화하는데 좋지 않다는 인상을 받고 있습니다. SSE를 사용하지만 많은 불필요한 작업을 수행합니다. libstdC++의'unique_ptr'가 deleter와 pointer의 압축 된 쌍을 구현하기 위해'tuple'을 사용하기 때문에 아마도 튜플은 최적화하기가 어려울 수 있습니다. – dyp

+0

@dyp 언어를 변경하는 대신 옵티마이 저를 더 좋게 만드는 이유와 같습니다. 또는 최적화 된 라이브러리 기반'튜플 (tuple) '보다 압축 된 튜플 관용구를 표현하는 방법을 찾아야합니다. 압축 된'tuple'을 최적화하는 것이 어렵다면, 아마도 내장 된'std :: tuple'을 가질 수 있을까요? 그것은 아마도 멀리 갈 것입니다. 압축 된'std :: tuple'을 쉽게 구현할 수있는 빌트인 원시 제품 유형이 있는가? – Yakk

+0

libC++에는 전용'compressed_pair' 유형이 있습니다. 이미 도움이되었다고 생각합니다. 컴파일 시간은 적어도 있습니다. Howard Hinnant는 퍼포먼스의 이유로 복사/이동 + 스왑 숙어를 좋아하지 않는 것처럼 보였습니다. – dyp