2013-04-07 3 views
14

다음 코드를 사용하여 unordered_set<Interval>을 만듭니다. 이것은 잘 컴파일됩니다. 이 코드를 사용하여 삽입 할 때사용자 지정 해시 함수를 사용하여 unordered_set에 삽입

struct Interval { 
    unsigned int begin; 
    unsigned int end; 
    bool updated; //true if concat. initially false 
    int patternIndex; //pattern index. valid for single pattern 
    int proteinIndex; //protein index. for retrieving the pattern 
}; 

struct Hash { 
    size_t operator()(const Interval &interval); 
}; 


size_t Hash::operator()(const Interval &interval){ 
    string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex); 
    return hash<string>()(temp); 
} 

unordered_set<Interval, string, Hash> test; 

그러나, 나는 컴파일 할 수 없습니다 :

for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){ 
    test.insert((*i)); 
    } 

또한, 나는 문제가 오류 메시지에서 무엇인지 확인할 수 없습니다. 나는 단지 1 개 인자를 제공하는 생각

note: candidate is: 
note: size_t Hash::operator()(const Interval&) 
note: candidate expects 1 argument, 2 provided 

...

사람이 내 삽입 코드에 문제가 있음을 볼 수 있습니까 : 여기

는 샘플입니다? 가능한 한 도와주세요. 저는 지금 꽤 오랫동안 해결책을 찾고있었습니다.

편집 :

여기 새로운 인스턴스 코드입니다 : unordered_set<Interval, Hash> test; 는 그러나, 나는 여전히 오류 메시지의 슬루를 수신하고 있습니다. 예 :

note: candidate is: 
note: size_t Hash::operator()(const Interval&) <near match> 
note: no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’ 
+0

내 대답이 업데이트되었습니다. 수정 내용에서 설명하는 문제가 해결되어야합니다. –

+0

http://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as- the-key –

답변

25

첫 번째 문제 : 당신은 unordered_set<> 클래스 템플릿의 사용자 인스턴스에 대한 두 번째 템플릿 인수로 string을 전달하는

. The second argument should be the type of your hasher functorstd::string은 호출 가능 개체가 아닙니다.

은 아마 쓸 의미 : 사람들은 C++ 표준 라이브러리의 알고리즘의 이름이기 때문에

unordered_set<Interval, /* string */ Hash> test; 
//      ^^^^^^^^^^^^ 
//      Why this? 

또한, 나는 당신의 (회원) 변수 beginend이 아닌 다른 이름을 사용하는 것이 좋습니다 것입니다.

두 번째 문제는 :

당신은 마음 that the hasher function should be qualified as const에 두어야

, 그래서 당신의 펑은 다음과 같아야합니다

struct Hash { 
    size_t operator() (const Interval &interval) const { 
    //           ^^^^^ 
    //           Don't forget this! 
    string temp = to_string(interval.b) + 
        to_string(interval.e) + 
        to_string(interval.proteinIndex); 
    return (temp.length()); 
    } 
}; 

세 번째 문제 : 마지막으로

, 당신은 std::unordered_set을 원하는 경우 유형이 Interval 인 객체를 사용할 수 있으려면 해시와 일치하는 항등 연산자를 정의해야합니다. 기능. 기본적으로 std::unordered_set 클래스 템플릿의 세 번째 매개 변수로 형식 인수를 지정하지 않으면 operator ==이 사용됩니다.

현재 Interval에 대해 operator ==의 과부하가 없으므로 제공해야합니다.예를 들면 :

inline bool operator == (Interval const& lhs, Interval const& rhs) 
{ 
    return (lhs.b == rhs.b) && 
      (lhs.e == rhs.e) && 
      (lhs.proteinIndex == rhs.proteinIndex); 
} 

결론 :

위의 모든 변경 후에는 코드가이 live example에서 컴파일 볼 수 있습니다.

+0

. 도와 주셔서 감사합니다! – user2052561

+0

@ user2052561 : 더 많은 수정 사항을 포함하도록 답변을 업데이트했습니다. –

+0

와우! 고마워. 이것은 처음으로'unordered_set's를 사용했습니다 ... – user2052561