2012-08-03 15 views
5

Ben oldukça büyük bir proje için unordered_set kullanmak ve emin ben doğru küçük bir örnek çalıştı kullanıyordum yapmak zorunda. Ben derlerkenbildirilmesi ++?

#include <iostream> 
#include <unordered_set> 
using namespace std; 

class Foo { 
    private: 
    int x; 
    public: 
    Foo(int in) {x = in;} 
    bool operator==(const Foo& foo) const {return x == foo.x;} 
    size_t hash(const Foo& foo) const {return x;} 
}; 

int main() { 
    Foo f1(3); 
    unordered_set<Foo> s; 
    s.insert(f1); 
    return 0; 
} 

alıyorum: benim karma işlevi görmek istemiyor gibi görünüyor

/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const': 
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE12_M_hash_codeERKS1_[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(Foo const&) const]+0x19): undefined reference to `std::hash<Foo>::operator()(Foo) const' 
/tmp/cc3KFIf4.o: In function `std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const': 
hashset.cc:(.text._ZNKSt8__detail15_Hash_code_baseI3FooS1_St9_IdentityIS1_ESt8equal_toIS1_ESt4hashIS1_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE15_M_bucket_indexEPKNS_10_Hash_nodeIS1_Lb0EEEj[std::__detail::_Hash_code_base<Foo, Foo, std::_Identity<Foo>, std::equal_to<Foo>, std::hash<Foo>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(std::__detail::_Hash_node<Foo, false> const*, unsigned int) const]+0x28): undefined reference to `std::hash<Foo>::operator()(Foo) const' 
collect2: ld returned 1 exit status 

ama düşündüm "hash" varsayılan işlev adı oldu. Hash doğru tanımladı mı? Ya da ben açıkça ikinci şablon bağımsız değişken olarak ayrı bir karma sınıf bildirmek gerekiyor?

+1

karma işlevi ekstra şablon parametresi olarak geçirilir. (Tercihen) bir funkere ihtiyacınız var ve 'unordered_set s (FooHasher());' – Xeo

cevap

8

Xeo'nun yorumlarına bir alternatif olarak, unordered_set'u başlatmadan önce std::hash için bir uzmanlık sağlayabilirsiniz.

namespace std { 
    template <> 
    struct hash<Foo> { 
     size_t operator() (const Foo &f) const { return f.hash(f); } 
    }; 
} 

sizin hash yöntemine foo parametre bana yabancı gibi görünüyor, ama sağlanan arayüzüne ihtisas uyguladı.

+0

Tamam, işe yaradı. Aslında fazladan bir parametre almak benim hash fonksiyonu için değil mi, bu bir yazım hatası olduğunu. size_t hash() const {return x;} olmalıdır. Kafamın karıştığı tek şey neden operatör (=) ile yaptığım gibi bir hash() yapamıyorum? Operatör için == Ekstra bir şey yapmak zorunda değildim. – user1575106

+0

user1575106 @: Farklı API'leri farklı gereksinimlere sahip olacaktır. Standart yazarlar, herkesin isteğine hitap edemez ve verilen arayüz, sınıfı değiştirmeden farklı karma algoritmaları denemeyi kolaylaştırır. – jxh