2010-12-01 3 views
2

나는 unordered_set의 생성자를보고 있습니다. 해시 버킷의 수를 설정하지 않고 사용자 정의 할당 자 인스턴스로 unordered_set을 구성 할 수 있습니까? 커스텀 할당자를 원하기 때문에 실제로 구현 세부 사항을 망칠 필요가 없으며, 유형은 기본값에 대한 정의를 제공하지 않습니다. MSDN은 생성자에 대해 세 가지 오버로드를 제공하며 그 중 어느 것도 유용하지 않습니다.std :: unordered_set 생성자

편집 : 신성한 허튼 소리. std :: hash의 STL 구현은 사용자 정의 할당 자 유형이있는 문자열을 전문으로하지 않습니다. 명시 적 typedefs std :: string 및 std :: wstring 만 수행 할 수 있습니다. 내 말은, 난 임의의 문자열을 해시하려고하지 않는 것을 이해할 수 있지만 사용자 정의 할당자가 있기 때문입니다. 이것은 나를 싫어해.

tokens(std::unordered_set<string>().bucket_count(), std::hash<string>(), std::equal_to<string>(), stl_wrapper::hash_set<string>::allocator_type(this)) 
template<typename Char, typename CharTraits, typename Allocator> class std::hash<std::basic_string<Char, CharTraits, Allocator>> 
    : public std::unary_function<std::basic_string<Char, CharTraits, Allocator>, std::size_t> { 
public: 
    size_t operator()(const std::basic_string<Char, CharTraits, Allocator>& ref) const { 
     return std::hash<std::basic_string<Char, CharTraits>>()(std::basic_string<Char, CharTraits>(ref.begin(), ref.end())); 
    } 
}; 

중복 된 구성 및 복사가 가능합니까? Ewwwww.

+0

편집 관련 : yup, afraid so. 'std :: hash'는 약간 부족합니다. 특히 표준은 UDT (사용자 정의 할당자를 사용하는 문자열 포함)를보다 쉽게 ​​만들 수 있도록 바이트 시퀀스를 해시하는 함수를 제공해야한다고 생각합니다. 하지만 교대로 할당 된 문자열은 위임 된 '해시'전문화와 관련이 없기 때문에 여러분은 도움이되지 않는 상태입니다. AFAIK 당신은 단지 자신의 해시 알고리즘을 선택한 다음 전문화를 작성하거나 컨테이너에 해시를 지정해야합니다. –

+0

@ 스티브 :별로. basic_string 생성자는 반복자를 사용할 수 있으므로 실제로 할당자가 무의미한 것으로 확장하는 것은 그리 어렵지 않지만 중복 복사가 포함되어 RAEG가됩니다. – Puppy

+0

@DeadMG : 그래, 왜 사용자 정의 할당자를 사용하는지에 달려있다. 프로그램의 모든 할당이 할당자를 통과하도록하려면 중복 복사 일뿐만 아니라 전체 복사가 실패합니다. –

답변

2

이상하게 들리지만 옳습니다. 가능한 모든 매개 변수 조합을 지원하는 것은 과도하다고 생각했습니다. 기본값이 있습니다.

내가 처리 할 수있는 가장 좋은 방법은 모든 기본 설정으로 빈 unordered_set을 생성하고, unordered_set::bucket_count을 사용하여 기본 버킷 수를 얻은 다음 실제로 원하는 컨테이너를 인스턴스화 할 때이를 입력으로 사용하는 것입니다.

unordered_set<int> temp; 
size_t buckets = temp.bucket_count; 
unordered_set<string> actual(buckets, Hash(), Pred(), 
    YourAllocator(param1 /*, etc */)); 
+0

커스텀 할당자를 디폴트로 구축 할 수 없다면 그렇게 할 수 없습니다. – Puppy

+0

편집 작업별로 코드를 작성하지 않는 이유는 무엇입니까? –

+0

@Steve : YourAllocator()는 컴파일러 오류이므로 기본 생성자가 없기 때문입니다. – Puppy

0

당신이 Allocator를 작성하기 때문에, 그것은 모두 모두 후 메모리 관련 : 당신이 원하지 않는 경우

스티브 방법의 마음을 준이다, 너무 버킷의 수를 제어하는 ​​것이 합리적이다 에, 지금 내가 도우미 함수를 :) 제안하자

template <typename T> 
size_t number_buckets() 
{ 
    std::unordered_set<T> useless; 
    return useless.bucket_count(); 
} 

그리고 그와

, 조금 (단순) 도우미 :

template <typename T, typename Hash, typename Pred, typename Allocator> 
std::unordered_set<T,Hash,Pred,Allocator> 
    make_unordered_set(Hash const& hash, Pred const& pred, Allocator const& alloc) 
{ 
    static size_t const nbBuckets = number_buckets<T>(); 
    return std::unordered_set<T,Hash,Pred,Allocator>(nbBuckets, hash, pred, alloc); 
} 

작품 꽤 잘 auto과 : 또한, 물론, 단순히 좋아 구현 중 일정한 찢어 수

auto set = make_unordered_set<std::string>(Hash(), Pred(), Allocator(1,2,3)); 

.

+0

아니요, 얼마나 많은 메모리가 할당되는지 여부와 해당 알고리즘의 구현 세부 사항을 제어하고 둘 모두를 제어하기 때문에 둘 다 제어하는 ​​것이 의미가 없으며 다른 알고리즘은이를 측정합니다. 이 둘은 반드시 서로 관련이있는 것은 아닙니다. – Puppy