Corgi Dog Bark

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C++] Priority_Queue, Set, Map 의 정렬 Custom 하기 - with. lambda
    카테고리 없음 2022. 12. 9. 21:05
    반응형

    안녕하세요. 이번 글의 주제는 

    Map과 Set 그리고 Priority_Queue 등 C++에서 자주 쓰이는 자료구조의 정렬 기준을 커스텀하는 방법에 대해서 알아보겠습니다. 우선 Priority_Queue에 대해서 설명을 드리겠습니다. 

     

     


    방법 1

    auto comp = [](int x, int y) { return x < y; };

    다음과 같은 비교함수를 사용해서, set의 비교 함수로 넣어주겠습니다.

     

    그럼 람다 함수를 set 의 템플릿 인자로 넣기 전에, Functional의 function 객체를 사용해서 한번 wrapping 해주었습니다.

    // 1. funciontal 객체로 람다함수를 감싸 넣어주기.
    auto Custom1 = set<int, function<bool(int, int)>>(comp);
    
    Custom1.insert({1, 2, 3, 4, 5, 1, 2, 3, 4, 5});
    copy(begin(Custom1), end(Custom1), ostream_iterator<int>(cout, " "));
    cout << endl;

     

     

    방법 2

    2번째 방법은 함수 포인터를 사용한 방법입니다. 마찬가지로 함수 포인터 타입을 set의 비교 함수 템플릿 인자로 넣어주어 타입을 명시적으로 나타내 주었습니다,

     

     // 2. 함수 포인터를 이용한 구현.
    auto Custom2 = set<int, bool (*)(int, int)>(comp);
    
    Custom2.insert({1, 2, 3, 4, 5, 1, 2, 3, 4, 5});
    copy(begin(Custom2), end(Custom2), ostream_iterator<int>(cout, " "));
    cout << endl;

     

     

    방법 3

    3 번째 방법은 decltype을 통한 타입 추론을 템플릿 인자로 넣는 방법입니다. 이때 decltype을 사용하여, 타입을 나타내 주도록 하였습니다.

    // 3. decltype 을 통한 타입추론을 통한 구현
    auto Custom3 = set<int, decltype(comp)>(comp);
    
    Custom3.insert({1, 2, 3, 4, 5, 1, 2, 3, 4, 5});
    copy(begin(Custom3), end(Custom3), ostream_iterator<int>(cout, " "));
    cout << endl;

     

     

    방법 4

    4 번째 방법은 Functor 객체 템플릿 인자로 넣는 방법입니다.  이 부분은 1~3 방법과 조금 다른데, 코드 보고 설명드리겠습니다.

    // 4. Functor 객체를 사용한 구현
    struct CompareFunc {
      CompareFunc() = default;
    
    	template<typename T>
    	bool operator()(const T l, const T r) const {
        return l < r;
      }
    };
    
    
    set<int, CompareFunc> Custom4{};
    Custom4.insert({1, 2, 3, 4, 5, 1, 2, 3, 4, 5});
    copy(begin(Custom4), end(Custom4), ostream_iterator<int>(cout, " "));
    cout << endl;

    여기서 1~3번과 다르게 Set 함수에 Functor 객체를 직접 넣어주었습니다. 이것이 가능한 이유는 Set 함수 내부에서, 함수 객체를 생성하기 때문입니다. 람다 함수를 직접 넣게 되면, 람다 함수는 직접적인 생성자가 존재하지 않기 때문에, 컴파일 에러가 발생하게 됩니다.

    set 에서 key_compare() 즉, 비교 함수의 생성자를 호출하는 부분.

     

    따라서 Functor 로 작성된 CompareFunc을 사용하여, 생성자를 Default로 사용해주고, operator를 오버 로딩하여, 비교 함수로 작성할 수 있었습니다.

     

     


     

    Reference

    1. https://en.cppreference.com/w/cpp/utility/functional/function

    2. https://stackoverflow.com/questions/4686507/lambda-expression-vs-functor-in-c

    3. https://stackoverflow.com/questions/2620862/using-custom-stdset-comparator

     

     

     

    반응형

    댓글

Designed by Tistory.