2016-06-09 18 views
6

Yinelemeyle uğraşırken, bir std::unordered_multimap anahtar içeriğinin benzersizliğini merak ediyordum.Anahtar benzersizliği hakkında std :: unordered_multimap

Ben noktayı anlatmaya çalışacağım: Ben, bu veriler Hash veya KeyEqual öğelerinde düşünülmemelidir haritasında kilit türü ile bazı verileri ilişkilendirmek gerekiyor ama ayrı harita ile depolama önlemek için ihtiyaç (optimizasyon amaçlı).

Yani benim fikri ile ilişkili kodu aşağıdadır:

sorunu bu çalışması beklenir, anahtar ilk unsuru olarak alınan gerçeği hakkında hiçbir garantisi yok olmasından kaynaklanmaktadır
struct Key { 
    void* data; 
    mutable bool attribute; 

    Key(void* data) : data(data), attribute(false) { } 
    bool operator==(const Key& other) const { 
    return data == other.data; 
    } 
}; 

struct KeyHash { 
    size_t operator()(const Key& key) const { 
    return std::hash<void*>()(key.data); 
    } 
}; 

class Foo { 
public: 
    int i; 
    Foo(int i) : i(i) { } 
}; 

std::unordered_multimap<Key, Foo, KeyHash> map; 

Tek bir öğeye eşlenen std::pair<const Key, Foo> her zaman aynıdır. Bir pairconst Key ait olmak ben

void* target = new int(); 
map.emplace(std::make_pair(target, Foo(1))); 
map.emplace(std::make_pair(target, Foo(2))); 


auto pit = map.equal_range(target); 
pit.first->first.attribute = true; 
std::cout << std::boolalpha << (++pit.first)->first.attribute << endl; 

yaparsanız bu ne düşünüyordum doğruluyor false verir, böylece haritadaki her eleman, değerine göre anahtarın kopyasını sahip olduğunu benziyor. Yani, aynı tuşa sahip birden fazla değere sahipseniz (std::unordered_map'u kullandığınızdan bu yana istediğinizde) anahtarları depolamak için çok fazla alan boşa harcanır.

bana anahtarla niteliğini çifti sağlar ama Yineleyicilerin iki düzeyde çalışmayı gerektirdiğinden daha az temiz herşeyi yapar

struct Value 
{ 
    std::vector<Foo> foos; 
    bool attribute; 
}; 

std::unordered_map<void*, Value> map; 

gibi başka bir çözüm yerine bir şey görmüyorum.

Göremediğim başka çözümler var mı?

+0

Yalnızca "boost :: multiindex' – Slava

+2

" eşlemini kullanın [target] = Foo (1); 'std :: unordered_multimap' aşırı yüklenmiyor' işleç [] ' –

+0

Gereksinimlerinizin ne olduğu açık değil. Herhangi bir şans ile std :: unordered_map > 'gibi bir şey mi arıyorsunuz? Bu, anahtarı çoğaltmaksızın birden fazla değeri aynı anahtarla birleştirir. –

cevap

2

23.5.5.1 Sınıf şablonu unordered_multimap genel [unord.multimap.overview]

1 bir unordered_multimap eşdeğer anahtar (her anahtar değeri birden fazla kopyasını ihtiva edebilir unordered_multimap örneğini destekleyen bir sırasız birleştirici kaptır) ve bu, başka bir tip mapped_type değerini anahtarlarla ilişkilendirir. Unordered_multimap sınıfı, ileri yineleyicileri destekler. Sonra potansiyel bir unordered_map<K, vector<V>> daha uygun olabilir anahtarın tek bir kopyasını isterseniz

bir unordered_multimap, anahtarın birden fazla kopyasını içerebilir.

İlgili konular