2009-07-25 3 views
4

두 가지 유형의 변수 중 하나를 사용하여 UDT의 벡터를 정렬하려면 표준 라이브러리 정렬에서이 작업을 수행 할 수 있습니까? 아니면 내 자신의 정렬을 작성해야합니까? 기능. 예를 들어표준 라이브러리 정렬 및 사용자 정의 형식

당신은

struct MyType{ 
int a; 
int b; 
}; 

vector<MyType> moo; 

// do stuff that pushes data back into moo 

sort(moo.begin(), moo.end()) // but sort it by lowest to highest for a, not b 

는 그래서 다음 stdlib 정렬을 사용하여이 가능한이 있다면? 감사.

답변

8

형식에 "bool operator < (...) const" 및 복사 생성자 (컴파일러 생성 또는 사용자 지정)를 구현하는 경우 표준 함수를 사용할 수 있습니다.

struct MyType { 
    int a; 
    int b; 
    bool operator < (const MyType& other) const { 
     ... // a meaningful implementation for your type 
    } 
    // Copy constructor (unless it's a POD type). 
    MyType(const MyType &other) 
     : a(other.a), b(other.b) { } 
    // Some other form of construction apart from copy constructor. 
    MyType() 
     : a(0), b(0) { } 
}; 

대안 대신 연산자 "<" 구현 sort()에 세 번째 인자로 순서화 기능 (또는 펑)를 통과 할 수있다.

bool type_is_less(const MyType& t1, const MyType& t2) { ... } 
... 
std::sort(c.begin(), c.end(), type_is_less); 

이 다음과 같은 상황에서 유용

  1. 당신이 어떤 이유로 든 운영자 "<"을 구현하지 않으려는,
  2. 당신은 내장 또는 포인터 타입의 컨테이너를 정렬 할 필요가 운영자에게 과부하가 걸리지 않도록하십시오.
  3. 다른 순서를 사용하여 시퀀스를 정렬하려고합니다. 예 : 이름/성 멤버가 성을 기준으로 정렬 된 구조체를 원할 때가 있습니다. 두 개의 다른 함수 (또는 펑터)는 그러한 옵션을 사소한 것으로 만듭니다. 당신은이 혹시 b에 따라이를 정렬 할 경우 단점이있다

    bool operator<(const MyType& lhs, const MyType& rhs) {return lhs.a<rhs.a;} 
    

    :

    당신은 당신의 클래스 operator< 과부하 수 :

+1

또 다른 옵션은 자신의 유형에'std :: less'를 특화시키는 것입니다. 이렇게하면 매번 (실제로 하나의 합리적인 정의가 있기 때문에) 펑터를 넘겨 줄 필요가 없지만 여러분의 타입은'operator <'를 얻지 못합니다. –

+0

type_is_less는 "함수 객체"(연산자를 오버로드하는 객체) 일 수도 있습니다. – newacct

+1

이 연산자는'const'가 아니라는 점에서 심각한 결함이 있습니다. 즉, 비교 상수의 왼쪽을 고려하는 코드에서는 작동하지 않습니다. (BTW, 나는이 잘못을 자주 보았으며, 이것만으로도이 운영자를 글로벌하게 만드는 데는 충분합니다. 훨씬 적은 사람들이 그렇게 잘못 생각합니다.) – sbi

3

이 작업을 수행하는 세 가지 방법있다 운이 좋다.

유형에 맞게 std::less을 전문으로 지정할 수도 있습니다. 따라서 이이 의미에 대해 operator<을 납치하지 않고 작동합니다 (그리고지도에서 키를 입력하는 것과 같은 다른 작업). 그러나 a에 대한 범용 비교 구문을 여전히 납치하는 반면 코드의 다른 위치에서는 b에 따라 유형을 비교할 수 있습니다.

또는이 같은 자신의 비교기를 쓸 수는 :

struct compare_by_a { 
    bool operator()(const MyType& lhs, const MyType& rhs) const 
    {return lhs.a<rhs.a;} 
}; 

(참고 :.. const을 운영자가 꼭 필요한 것은 후 나는 아직도하지만, 그것은 좋은 스타일을 고려) 이것은 일반 - 잎 목적의 비교 수단은 정의되지 않았다; 그래서 어떤 코드가 당신이 인식하지 못하게 그들을 사용하기를 원한다면, 컴파일은 에러를 내고 그것을 당신에게 알려줍니다. 이 비교기 또는 다른 비교기를 비교할 필요가있는 곳에서 선택적으로 그리고 명시 적으로 사용할 수 있습니다.