2011-04-28 4 views
6

고유 키를 가진 구조체가 있습니다. 이 구조체의 인스턴스를 세트에 삽입하고 싶습니다. 이 작업을 수행하려면 < 연산자가 오버로드되어야하므로 set이 삽입을 수행하기 위해 비교할 수 있어야합니다.C++에서 구조체 집합을 갖는 방법

다음은 작동하지 않습니다

#include <iostream> 
#include <set> 
using namespace std; 
struct foo 
{ 
     int key; 
}; 

bool operator<(const foo& lhs, const foo& rhs) 
{ 
     return lhs.key < rhs.key; 
} 

set<foo> bar; 

int main() 
{ 
    foo *test = new foo; 
    test->key = 0; 
    bar.insert(test); 
} 
+6

Test.cpp에 : 20 : 오류 : 호출 일치 기능을 표준 '으로 :: 설정 이하, 표준 : : 할당 > :: 삽입 (foo * &) ' 오류가 꽤 분명해 보입니다. 객체가 있어야하는 위치에 포인터를 놓으려고합니다. – dcousens

+0

질문을 편집 할 수있는 것은 좋지만 그 의미를 변경해서는 안됩니다. 이것은 어떤 (아마도 정확한) 대답을 무효화하고 미래의 독자가 편집을 먼저 보도록 강요합니다. 같은 사람이 짧은 시간 내에 몇 가지 질문을 게시하는 것과 관련하여 StackOverflow에 대한 제한이 없습니다. 사실, 그건 좋은 생각입니다. – ereOn

답변

10

이 도움이 될 :

struct foo 
{ 
    int key; 
}; 

inline bool operator<(const foo& lhs, const foo& rhs) 
{ 
    return lhs.key < rhs.key; 
} 

당신이 네임 스페이스를 사용하는 경우, 동일한 네임 스페이스의 operator<() 함수를 선언하는 것이 좋습니다. 편집 한 후 완성도를 위해서


및 기타가 지적한 것처럼, 당신은 foo가 예상되는 foo*를 추가하려고합니다.

포인터를 실제로 처리하려면 foo*을 스마트 포인터 클래스 (auto_ptr, shared_ptr, ...)로 묶어야합니다.

두 경우 모두 foo에서 작동하는 오버로드 된 operator<의 이점은 누적되며 foo*이 아니라는 점에 유의하십시오.

+0

작동하지만 세트에 삽입 할 때 작동하지 않습니다. 내 질문에 코드를 포함하도록 변경했습니다. –

+3

이 질문은 원래 질문에 대한 대답으로, 올바른 것으로 선택하는 것이 좋습니다. 적응 된 질문은 단순히 구문 오류 일뿐입니다. – dcousens

+0

나는 성능을 향상시키는 함수에서 키워드 [''inline'] (http://www.cprogramming.com/tutorial/lesson13.html)을 사용했다는 사실을 좋아했습니다! +1 –

3
struct Blah 
{ 
    int x; 
}; 

bool operator<(const Blah &a, const Blah &b) 
{ 
    return a.x < b.x; 
} 

... 

std::set<Blah> my_set; 

그러나, 나는 (정말 하나 Blah는 또 다른 Blah "보다"? 말을 이해 않음) 직관적 인 의미가하지 않는 operator< 오버로드를 좋아하지 않는다. 그렇지 않은 경우 대개 사용자 지정 비교 함수를 대신 제공합니다.

bool compareBlahs(const Blah &a, const Blah &b) 
{ 
    return a.x < b.x; 
} 

... 

std::set<Blah,compareBlahs> my_set; 
2

ereOn의 대답을 참조하십시오.

foo *test = new foo; 
test->key = 0; 
bar.insert(test); 

당신은 세트가 아닌 구조체에 포인터를 삽입 :

당신 코드의 진짜 문제는 이것이다.

bar.insert(*test); 
//  ^

편집 : 다음 insert로 변경하지만이 set에 복사됩니다로서 당신은, delete foo해야합니다. 당신은 클래스 내부의 operator <를 오버로드 할 수

2

- 또는 단지합니다 (set가 포인터의 주소에 따라 정렬합니다 배열이 "이상한"되기 때문에 포인터 set은 좋은 생각이 아니다 사용) 스택에 생성 또한

struct foo 
{ 
    int key; 
    bool operator < (const foo &other) const { return key < other.key; } 
}; 
당신은 다음 선언으로 set<foo> bar;을 사용하려는 경우, 당신은 같은 값을 삽입해야합니다 귀하의 질문에

,

bar.insert(*test); 

하지만, 같이 요로, 좋은 생각되지 않습니다 중복 복사본을 만들고 있습니다.

foo *test = new foo; 
test->key = 0; 
bar.insert(test); // BROKEN - need to dereference ala *test 
// WARNING: need to delete foo sometime... 

은 ... 당신은 간단하게 사용할 수 있습니다 ...

struct foo 
{ 
    foo(int k) : key(k) { } 
    int key; 
}; 

가 그런 것이 아니라, 추가 :

+0

>.> 실제로 std :: unordered_set에는 작동하지 않습니다. – Dmitry

2

할 수있는 가장 좋은 것은 foo에에게 생성자를 제공하는 것입니다

bar.insert(foo(0)); 
1

문제가 설정되지 않았습니다. 귀하의 test 개체에 있습니다. 자바 스타일을 사용하고 있습니다. C++에서, 우리는 그냥 쓸 :

set<foo> bar; 

int main() 
{ 
    foo test; // Local variable, goes out of scope at } 
    test.key = 0; 
    bar.insert(test); // Insert _a copy of test_ in bar. 
} 
관련 문제