[C++] std::sort의 compare 인자 : functor, 익명 구조체, 람다

김민정·2025년 9월 17일
1

C++

목록 보기
1/1
post-thumbnail

문제 발생

struct compareString 
{ 
    bool operator()(string a, string b) const {return a+b > b+a;} 
}; 

string solution(vector<int> numbers) 
{ 
    ...

    sort(numbers_string.begin(), numbers_string.end(), compareString); 

    ...
}

코테 풀이 중 algorithm 헤더의 sort 함수에 커스텀한 compare 인자를 넣으려고 했는데, 아래와 같은 오류가 발생했다.

/solution0.cpp:22:56: error: 'compareString' does not refer to a value
    sort(numbers_string.begin(), numbers_string.end(), compareString);
                                                       ^
/solution0.cpp:7:8: note: declared here
struct compareString 
       ^
1 error generated.

오류를 직역하자면, 'compareString'은 값을 참조하지 않는다는 뜻이다.

위 코드에서 compareString은 구조체의 이름이지, 객체가 아니다.

하지만 compare 인자는 class이기 때문에 객체를 넣어주어야 한다.
=> 즉, 구조체든 함수든 객체를 생성하여 넣어주어야 한다.


문제 해결

[1] functor 임시 객체 생성

struct compareString 
{ 
    bool operator()(string a, string b) const {return a+b > b+a;} 
}; 

string solution(vector<int> numbers) 
{ 
    ...

    sort(numbers_string.begin(), numbers_string.end(), compareString()); 

    ...
}

기본 생성자로 임시 객체를 생성하여 인자로 넣어준다.
이때, compareString 구조체는 함수처럼 동작하는 객체이기에 functor이다.

[2] 익명 구조체 생성

struct  
{ 
    bool operator()(string a, string b) const {return a+b > b+a;} 
}compareString; 

string solution(vector<int> numbers) 
{ 
    ...

    sort(numbers_string.begin(), numbers_string.end(), compareString); 

    ...
}

익명 구조체 정의와 객체 생성을 동시에 한 뒤, 이를 인자로 전달한다.

[3] 람다 사용

string solution(vector<int> numbers) 
{ 
    ...

    sort(numbers_string.begin(), numbers_string.end(), 
    [](const string& a, const string& b){ return a+b > b+a; }; 

    ...
}

익명 함수 객체인 람다를 사용하여 바로 compare 인자로 전달한다.


functor vs 람다

람다가 훨씬 가독성이 좋은데, 왜 굳이 functor을 써야할까? 의문이 들었다.
게다가 std::function도 있는데, 왜 functor 라는게 있는가 싶어서 짱피티한테 물었더니 아래와 같이 대답해주더이다.

functor

  • 재사용 가능 : 동일한 비교 로직을 여러 곳에서 쓰거나, 여러 알고리즘에 적용할 때 유용함
  • 상태 저장 가능 : 람다도 캡처로 가능하지만, 구조체처럼 멤버 변수로 관리하면 명시적이라 편리함
  • 템플릿 인자로 전달 가능 : functor는 타입 자체를 전달할 수 있음

람다

  • 가독성 좋음
  • 일회성임
  • C++11 이후부터 사용 가능 (std::function도 마찬가지)
profile
📝 공부노트

0개의 댓글