boost :: unordered_map에서 키에 맞춤형 유형을 사용하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/1829639

문제

현재 프로젝트에서 Boost의 해시 맵 구현을 사용하고 있으며 키에 대한 사용자 정의 유형을 구현하려고합니다. 키로 사용할 단일 128 비트 데이터 타입으로 결합하려는 4 개의 서명되지 않은 정수가 있습니다.

나는 내 스토리지 역할을하는 4 개의 요소로 구성된 32 비트 정수 배열로 구조물을 만들었습니다. 솔직히 말해서 Boost의 해시 맵이 어떻게 작동하는지 잘 모르겠으므로 여기서 무엇을하고 있는지 잘 모르겠지만 Boost 문서를 따랐습니다 (http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html) boost를 확장하기 위해 :: 해시를 위해, 그리고 해시 함수와 사용자 정의 비교 연산자를 만들었습니다.

이 사용자 지정 유형이 헤더에 정의되어 있습니다. 이것은 내 코드입니다.

#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

이제 실제로 Boost의 변환되지 않은 맵 에서이 유형을 사용하면 코드가 컴파일되지만 링크되지 않습니다. 링커는 여러 객체 파일에 여러 번 정의 된 기호가 있다고 주장합니다. 이지도에서 128 비트 유형을 작동시키고 싶습니다. 내가 망치고있는 것에 대한 팁, 또는 더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

정렬되지 않은 맵의 참여는 당신이 직면 한 문제에 거의 부수적입니다. 실제 문제는 당신이 정의하고 있다는 것입니다 hash_value 그리고 operator== 위의 헤더가 포함 된 모든 파일에서

당신은 이것을 다음 중 하나로 치료할 수 있습니다.

  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]);
}

다른 팁

링커는 여러 객체 파일에 여러 번 정의 된 기호가 있다고 주장합니다.

당신의 기능을 다음과 같이 선언하십시오 inline

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top