2013-02-12 4 views
1

다음 코드는 unordered_set을 정의합니다. 코드가 잘 컴파일됩니다. 그러나 발견을 호출 할 때 펑 던져 대신 람다 함수를 사용하여 :lambda를 사용하면 해시 함수가 예외를 throw 함 do

의 libC++ abi.dylib : 예외를 던지는라고 종료

#include <unordered_set> 

class pair_hash { 
    public: 
     size_t operator() (const std::pair<int, int> &x) const { 
      return std::hash<int>()(x.first)^std::hash<int>()(x.second); 
     } 
}; 

int main() { 
    std::unordered_set<std::pair<int, int>, pair_hash> temp; 
    temp.find(std::make_pair(0,0)); 


    std::function<std::size_t(std::pair<int , int>)> fpair_hash; 
    fpair_hash = [](const std::pair<int, int>& v) -> std::size_t 
    { 
     return std::hash<int>()(v.first)^std::hash<int>()(v.second); 
    }; 

    std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2; 
    //why does this not work? 
    temp2.find(std::make_pair(0,0)); 
    return 0; 
} 

그 소리 ++ -std = C++ 11 -stdlib = libc의 ++ -o 테스트 Test.cpp에

답변

3

decltype(fpair_hash) 그래서 당신은 단지 EMPT 설정 구축 std::function<std::size_t(std::pair<int , int>)>입니다 y 해쉬 함수. 이것은 그것이 작동되도록해야하지만, std::function를 사용하는 다형성 호출의 오버 헤드를해야합니다

std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2(10, fpair_hash); 

당신은 아마 그것을 필요가 없습니다 :

당신은 std::unordered_set의 생성자 함수를 제공해야

auto fpair_hash = [](const std::pair<int, int>& v) -> std::size_t 
{ 
    return std::hash<int>()(v.first)^std::hash<int>()(v.second); 
}; 

마지막으로 해시 함수가 실제로 좋지 않습니다. 모든 쌍 (x, x)0에 매핑합니다. 아마도 x^y 대신 x * 17 + y * 13 같은 것을 사용하면 충돌 가능성이 줄어 듭니다.

+0

'return std :: hash () (std :: hash () (v.first)^v.second);에 대해 논할 것이다. – Yakk