문제

무엇인가요 std::pair 왜 그것을 사용해야 하며 어떤 이점이 있습니까? boost::compressed_pair 가져오다?

도움이 되었습니까?

해결책

std::pair 두 값을 단일 개체로 그룹화하기 위한 데이터 유형입니다. std::map 키, 값 쌍에 사용합니다.

당신이 배우는 동안 pair, 확인해 보세요 tuple.그것은 같다 pair 그러나 임의의 수의 값을 그룹화하는 데 사용됩니다. tuple TR1의 일부이며 많은 컴파일러가 이미 표준 라이브러리 구현에 이를 포함하고 있습니다.

또한 이 책의 1장 "튜플"을 확인해 보세요. C++ 표준 라이브러리 확장:튜토리얼 및 참고자료 작성자: 피트 베커(Pete Becker), ISBN-13:자세한 설명은 9780321412997을 참조하세요.

alt text

다른 팁

compressed_pair 공간을 절약하기 위해 일부 템플릿 속임수를 사용합니다.C++에서는 객체(small o)가 다른 객체와 동일한 주소를 가질 수 없습니다.

그러니 당신이 있다고 해도

struct A { };

A의 크기는 0이 되지 않습니다. 그 이유는 다음과 같습니다.

A a1;
A a2;
&a1 == &a2;

허용되지 않습니다.

하지만 많은 컴파일러는 "빈 기본 클래스 최적화"를 수행합니다.

struct A { };
struct B { int x; };
struct C : public A { int x; };

여기는 괜찮습니다 B 그리고 C 같은 크기를 가지더라도 sizeof(A) 0이 될 수 없습니다.

그래서 boost::compressed_pair 이 최적화를 활용하고 가능한 경우 쌍의 유형 중 하나가 비어 있는 경우 이를 상속합니다.

그래서 std::pair 다음과 같을 수 있습니다(나는 좋은 거래, ctors 등을 생략했습니다).

template<typename FirstType, typename SecondType>
struct pair {
   FirstType first;
   SecondType second;
};

이는 다음 중 하나를 의미합니다. FirstType 또는 SecondType ~이다 A, 당신의 pair<A, int> 보다 커야합니다 sizeof(int).

하지만 만약 당신이 사용한다면 compressed_pair, 생성된 코드는 다음과 유사합니다.

 struct compressed_pair<A,int> : private A {
    int second_;
    A first() { return *this; }
    int second() { return second_; }
 };

그리고 compressed_pair<A,int> sizeof(int) 만큼만 커집니다.

함수에서 2개의 값을 반환해야 하는 경우가 있는데, 이를 위한 클래스를 만드는 것은 종종 과도한 작업입니다.

이러한 경우에는 std:pair가 유용합니다.

나는 Boost:compressed_pair가 크기 0의 멤버를 최적화할 수 있다고 생각합니다.이는 라이브러리의 무거운 템플릿 기계에 주로 유용합니다.

유형을 직접 제어하는 ​​경우에는 관련이 없습니다.

pressed_pair가 몇 바이트에 관심이 있다는 말을 들으면 이상하게 들릴 수 있습니다.그러나pressed_pair를 사용할 수 있는 위치를 고려할 때 실제로 중요할 수 있습니다.예를 들어 다음 코드를 살펴보겠습니다.

boost::function<void(int)> f(boost::bind(&f, _1));

위와 같은 경우에pressed_pair를 사용하면 갑자기 큰 영향을 미칠 수 있습니다.Boost::bind가 함수 포인터와 자리 표시자를 저장하면 어떻게 될까요? _1 회원으로서 그 자체로 또는 std::pair 그 자체?글쎄, 그것은 부풀어 오를 수 있습니다 sizeof(&f) + sizeof(_1).함수 포인터가 8바이트(특히 멤버 함수의 경우 드물지 않음)이고 자리 표시자에 1바이트(이유는 Logan의 답변 참조)가 있다고 가정하면 바인드 객체에 9바이트가 필요할 수 있습니다.정렬로 인해 일반적인 32비트 시스템에서는 최대 12바이트까지 커질 수 있습니다.

boost::function 구현 시 작은 개체 최적화를 적용하도록 권장합니다.즉, 작은 펑터, 직접 내장된 작은 버퍼 boost::function 객체는 펑터를 저장하는 데 사용됩니다.더 큰 펑터의 경우 메모리를 얻기 위해 new 연산자를 사용하여 힙을 사용해야 합니다.부스트 주변 버전 1.34, 채택하기로 결정되었습니다. 이 최적화, 매우 큰 성능상의 이점을 얻을 수 있다고 생각했기 때문입니다.

이제 이러한 작은 버퍼에 대한 합리적인(아직은 여전히 ​​매우 작은) 제한은 8바이트입니다.즉, 우리의 아주 간단한 바인드 객체는 ~ 아니다 작은 버퍼에 맞으므로 연산자 new를 저장해야 합니다.위의 바인드 객체가 compressed_pair, 자리 표시자는 빈 개체에 지나지 않기 때문에 실제로 크기를 8바이트(비멤버 함수 포인터의 경우 4바이트)로 줄일 수 있습니다.

따라서 단 몇 바이트에 대해 많은 생각을 낭비하는 것처럼 보일 수도 있지만 실제로는 성능에 상당한 영향을 미칠 수 있습니다.

한 쌍의 값을 저장하는 표준 클래스입니다.다음과 같은 일부 표준 함수에서 반환/사용됩니다. std::map::insert.

boost::compressed_pair 더 효율적이라고 주장합니다. 여기를 보아라

std::pair는 STL의 다른 컨테이너 클래스 몇 개에 유용합니다.

예를 들어:

std::map<>
std::multimap<> 

둘 다 std::키와 값 쌍을 저장합니다.

맵과 멀티맵을 사용할 때 쌍에 대한 포인터를 사용하여 요소에 액세스하는 경우가 많습니다.

추가 정보:Boost::compressed_pair는 쌍의 유형 중 하나가 빈 구조체일 때 유용합니다.이는 쌍의 유형이 다른 유형에서 프로그래밍 방식으로 추론될 때 템플릿 메타프로그래밍에서 자주 사용됩니다.그런 다음 일반적으로 "빈 구조체" 형태를 갖게 됩니다.

나는 템플릿 메타프로그래밍을 많이 하지 않는 한 "일반적인" 용도로 std::pair를 선호합니다.

이는 후드 아래에 두 개의 변수가 있는 구조일 뿐입니다.

나는 실제로 함수 반환에 std::pair를 사용하는 것을 싫어합니다.코드를 읽는 사람은 .first가 무엇인지, .second가 무엇인지 알아야 합니다.

내가 가끔 사용하는 절충안은 참조 이름을 명확하게 지정하면서 .first 및 .second에 대한 상수 참조를 즉시 생성하는 것입니다.

std::pair는 무엇이며 왜 사용해야 합니까?

이는 단순한 두 요소 튜플과 같습니다.의 첫 번째 버전에서 정의되었습니다. STL 컴파일러가 다음과 같은 보다 정교한 유형의 튜플을 구현하는 데 필요한 템플릿과 메타프로그래밍 기술을 널리 지원하지 않았던 시대에 Boost.Tuple.

많은 상황에서 유용합니다. std::pair 표준 연관 컨테이너에 사용됩니다.간단한 형태의 범위로 사용할 수 있습니다. std::pair<iterator, iterator> - 따라서 두 개의 반복자 대신 범위를 나타내는 단일 객체를 허용하는 알고리즘을 정의할 수 있습니다.(많은 상황에서 유용한 대안입니다.)

때로는 매개변수로든 반환 값으로든 항상 함께 전달하는 두 가지 정보가 있습니다.물론, 자신만의 객체를 작성할 수도 있지만 두 개의 작은 기본 요소 또는 이와 유사한 경우에는 한 쌍이 괜찮아 보일 때도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top