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?
Verwenden Sie einfach 'boost :: multiindex' – Slava
' map [Ziel] = Foo (1); '' std :: unordered_multimap' überlädt nicht 'operator []' –
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. –