2016-06-09 2 views
6

Ich frage mich über Eindeutigkeit eines Schlüsselobjekts innerhalb einer std::unordered_multimap, wenn es um Iteration geht.Garantien über Schlüsseleindeutigkeit in std :: unordered_multimap

Ich werde versuchen, den Punkt zu erklären: Ich brauche ein paar Daten mit dem Schlüsseltyp in der Karte zuzuordnen, diese Daten nicht in Hash oder KeyEqual Elementen in Betracht gezogen werden sollten, aber ich brauche es eine separate Karte zu vermeiden Lagerung mit es (zu Optimierungszwecken).

So ist der Code mit meiner Idee verbunden ist, ist die folgende:

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; 

Das Problem entsteht aus der Tatsache, dass, obwohl dies funktioniert gut, es gibt keine Garantien über die Tatsache, dass der Schlüssel als erstes Element abgerufen von Die std::pair<const Key, Foo> Zuordnung zu einem einzelnen Element ist immer gleich. Als ein pair von const Key es sich anhört, dass jedes Element in der Karte durch den Wert seiner Kopie des Schlüssels hat, so dass, wenn ich

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; 

tun Dies ergibt false, die bestätigt wird, was ich dachte. Es ist also viel Platz für die Speicherung von Schlüsseln verschwendet, wenn Sie mehrere Werte mit demselben Schlüssel haben (was Sie wollen, da Sie eine std::unordered_map verwenden).

Ich sehe keine andere Lösung, anstatt etwas wie

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

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

Was mir das Attribut mit dem Schlüssel paaren können, aber macht alles weniger sauber, da es mit zwei Ebenen von Iteratoren arbeiten erfordert.

Gibt es andere Lösungen, die ich nicht sehe?

+0

Verwenden Sie einfach 'boost :: multiindex' – Slava

+2

' map [Ziel] = Foo (1); '' std :: unordered_multimap' überlädt nicht 'operator []' –

+0

Es ist nicht ganz klar, was Ihre Anforderungen sind. Suchen Sie etwas wie 'std :: unordered_map >', zufällig? Das würde gerne mehrere Werte mit demselben Schlüssel verknüpfen, ohne den Schlüssel zu duplizieren. –

Antwort

2

23.5.5.1 Vorlage Klasse unordered_multimap Überblick [unord.multimap.overview]

1 Ein unordered_multimap ist ein ungeordneten assoziativen Container, der äquivalent Tasten (eine Instanz von unordered_multimap unterstützt kann mehrere Kopien von jedem Schlüsselwert enthalten,) und assoziiert Werte eines anderen Typs mapped_type mit den Schlüsseln. Die unordered_multimap-Klasse unterstützt Vorwärtsiteratoren.

Ein unordered_multimap können mehrere Kopien des Schlüssels enthalten, wenn Sie ein unordered_map<K, vector<V>> sein könnte besser geeignet dann möglicherweise eine einzelne Kopie des Schlüssels möchten.

Verwandte Themen