2009-12-01 2 views
2

지금 프로젝트에서 Boost의 해시 맵 구현을 사용하고 있으며 키에 대한 사용자 정의 유형을 구현하려고합니다. 필자는 4 개의 부호없는 정수를 하나의 128 비트 데이터 형식으로 결합하여 키로 사용하려고합니다.boost :: unordered_map의 키에 사용자 정의 유형을 사용하려면 어떻게해야합니까?

내 스토리지로 사용되는 4 개 요소의 32 비트 정수 배열로 구조체를 만들었습니다. 솔직히 말해서 Boost의 해시 맵이 어떻게 작동하는지 모르겠다. 그래서 내가 여기서 뭘하고 있는지 모르겠다.하지만 boost :: hash 확장을위한 Boost 문서 (http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html)를 따라 갔고 해시 함수를 만들었다. 뿐만 아니라 사용자 지정 비교 연산자가 포함됩니다.

이 사용자 정의 유형이 헤더에 정의되어 있습니다. 실제로 부스트의 정렬되지 않은지도에서이 형식을 사용할 때 내 코드 컴파일, 이제

#ifndef INT128_H_ 
#define INT128_H_ 

// Custom 128-bit datatype used to store and compare the results of a weakened hash operation. 
struct int128 
{ 
    unsigned int storage[4]; 

    /* Assignment operation that takes a 32-bit integer array of four elements. 
    This makes assignment of values a shorter and less painful operation. */ 
    void operator=(const unsigned int input[4]) 
    { 
     for(int i = 0; i < 4; i++) 
      storage[i] = input[i]; 
    } 
}; 

bool operator==(int128 const &o1, int128 const &o2) 
{ 
    if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
     o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]) 
     return true; 

    return false; 
} 

// Hash function to make int128 work with boost::hash. 
std::size_t hash_value(int128 const &input) 
{ 
    boost::hash<unsigned long long> hasher; 
    unsigned long long hashVal = input.storage[0]; 

    for(int i = 1; i < 3; i++) 
    { 
     hashVal *= 37; 
     hashVal += input.storage[1]; 
    } 

    return hasher(hashVal); 
} 

#endif 

하지만, 연결 실패 :이 내 코드입니다. 링커는 여러 객체 파일에 여러 번 정의 된 심볼을 가지고 있다고 주장합니다. 이 맵을 사용하여 128 비트 타입을 사용하고 싶습니다. 내가 망쳐 놓은 것에 대한 조언이나 더 좋은 방법이 있습니까?

+0

로 함수를 선언합니다. == 대신 XOR 연산자를 사용하는 이유는 무엇입니까? 또한 비교를 중첩하는 것에 대한 그 진술은 쓰레기입니다. C + + 논리 AND 연산자는 단락 회로 평가를하므로 절대적으로 더 많은 코드를 입력했습니다. – rlbond

+0

고정, 비판 주셔서 감사. – jakogut

답변

3

순서가 지정되지 않은지도는 사용자가 직면하는 문제와 거의 부수적입니다. 실제 문제는 위의 헤더가 포함 된 모든 파일에서 hash_valueoperator==을 정의한다는 것입니다.

다음 중 한 가지 방법으로이 문제를 치료할 수 :

  1. 을 모두 정의 인라인 함수와 그
  2. 그냥 헤더를 후자을 (그리고 경우

은 당신이 보통거야 것 선언 원하는) 이러한 함수의 정의를 .cpp 파일 (또는 C++ 소스 파일에 사용하는 확장명)으로 이동합니다. 그런 다음 해당 파일을 컴파일하고 결과 객체를 int128 유형을 사용하는 다른 코드와 연결합니다.

편집 : 당신은 여전히 ​​비교 청소기, 같은 것을 만들 수 있습니다

bool operator==(int128 const &o1, int128 const &o2) 
{ 
    return o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
      o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]); 
} 
+0

감사합니다. 이것은 완벽한 대답입니다. – jakogut

1

나는 기호를 여러 오브젝트 파일에서 정의 된 여러 번이 링커 주장.

내가 당신의 '연산자는 ==`올바른 생각하지 않는다 inline