[effective STL] 항목 20 : 연관 컨테이너에 포인터 넣을 때 비교 함수자 타입을 정해주기

2015. 12. 27. 22:17프로그래밍/Effective STL

728x90
728x90

Source

https://github.com/ElementalKiss/Cpp/blob/master/Example/AssociateContainerAndPointer.cpp


간단한 예제

1
2
3
4
5
6
7
8
9
    std::set<std::string* > ssp;
    ssp.insert(new std::string("koko"));
    ssp.insert(new std::string("love"));
    ssp.insert(new std::string("elki"));
    ssp.insert(new std::string("momo"));
 
    // 해당 방법으로 출력하며 원하는 순서가 나오지 않는다.
    // 그냥 넘겨주면 포인터 값으로 정렬하게 된다.
    std::for_each(ssp.begin(), ssp.end(), print);
cs


결과는 koko, love, elki, momo 순서로 나오게 된다.

입력 시 정렬이 되는 알파벳 순으로 정렬 되길 원하지만

실제 set에 들어가는 값은 string 객체의 포인터기 때문에

포인터 값의 순서로 set이 정렬된다.


그러므로 비교타입으로 동작할 함수자 클래스를 거의 항상 만들어야 된다.


Less 비교 함수자 타입 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    // Less 비교 함수자 타입 정의 // 포인터가 가리키는 값으로 정렬할 수 있게끔 한다.
    struct StringPtrLess :
        public std::binary_function<const std::string*const std::string*bool>
    {
        bool operator()(const std::string* ps1, const std::string* ps2) const
        {
            return *ps1 < *ps2;
        }
    };
 
    typedef std::set<std::string*, StringPtrLess> StringPtrSet;
    StringPtrSet newSsp;
 
    newSsp.insert(new std::string("koko"));
    newSsp.insert(new std::string("love"));
    newSsp.insert(new std::string("elki"));
    newSsp.insert(new std::string("momo"));
 
    std::for_each(newSsp.begin(), newSsp.end(), print);
cs


이렇게 하면 원하는 방법으로 정렬하여 값을 넣게 된다.


DereferenceLess 비교 함수자 템플릿 타입 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 함수자의 템플릿
struct DereferenceLess
{
    template <typename PtrT>
    bool operator()(PtrT pT1, PtrT pT2) const
    {
        return *pT1 < *pT2;
    }
};
 
//////////////////////////main////////////////////////////
 
    // DereferenceLess 비교 함수자 템플릿 타입 정의
    typedef std::set<std::string*, DereferenceLess> DereferencePtrSet;
    DereferencePtrSet anotherNewSsp;
 
    anotherNewSsp.insert(new std::string("koko"));
    anotherNewSsp.insert(new std::string("love"));
    anotherNewSsp.insert(new std::string("elki"));
    anotherNewSsp.insert(new std::string("momo"));
 
    std::for_each(anotherNewSsp.begin(), anotherNewSsp.end(), print);
cs


set 템플릿에 들어가는 세 개의 매개 변수가 모두 타입(type)이기 때문에 함수를 정의하여 넣으면 안된다.

내부적으로 인스턴스화하여 함수를 만들 수 있는 타입을 원하는 것.


포인터의 연관 컨테이너를 만드는 일과 컨테이너의 비교 타입을 지정하는 일은 실과 바늘의 관계라고 생각해두는게 좋다.



728x90
반응형