Da dies für Memoisierung ist, ist keine der beiden Optionen eine gute Idee.
Für einzigartige Schlüssel Container, emplace
und insert
(außer wenn insert
geben wird eine value_type
- das heißt, pair<const Key, Value>
) Speicher bedingungslos zuteilen kann und konstruieren den Schlüssel-Wert-Paar erste und dann das Paar zerstören und freigeben, den Speicher, wenn der Schlüssel existiert bereits; Das ist natürlich teuer, wenn Ihr Schlüssel bereits existiert. (Sie müssen dies tun, weil Sie im Allgemeinen den Schlüssel erstellen müssen, bevor Sie überprüfen können, ob er existiert, und der Schlüssel muss direkt an seinem endgültigen Ort erstellt werden.)
Sie wollen aber auch vermeiden, unnötigerweise den Schlüssel zu kopieren, also ist das Einfügen eines value_type
nicht gut - das Key
dort ist const-qualifiziert und kann daher nicht verschoben werden.
Schließlich möchten Sie auch zusätzliche Lookups vermeiden. Nicht so teuer wie eine Speicherzuweisung, aber immer noch gut, um sie zu speichern.
Daher müssen wir den Schlüssel zuerst suchen und nur emplace
aufrufen, wenn der Schlüssel nicht in der Karte ist. In C++ 11 ist nur eine homogene Suche zulässig, daher müssen Sie eine Kopie von args...
erstellen.
map<tuple<Args...>, int> cache;
auto key = std::make_tuple(args...);
auto it = cache.lower_bound(key); // *it is the first element whose key is
// not less than 'key'
if(it != cache.end() && it->first == key) {
// key already in the map, do what you have to do
}
else {
// add new entry, using 'it' as hint and moving 'key' into container.
cache.emplace_hint(it, std::move(key), /* value */);
}
In C++ 14, können Sie heterogenen Lookup tun, was bedeutet, dass Sie die Kopie, wenn Sie es wirklich brauchen sparen können:
map<tuple<Args...>, int, less<>> cache; // "diamond functor" enables hetergeneous lookup
auto key = std::tie(args...); // this is a tuple<const Args&...> - a tuple of references!
auto it = cache.lower_bound(key); // *it is the first element whose key is
// not less than 'key'
if(it != cache.end() && it->first == key) {
// key already in the map, do what you have to do
}
else {
// add new entry, copying args...
cache.emplace_hint(it, key, /* value */);
}
BTW mit großen Objekttupels als Kartenschlüssel nicht eine optimale Option IMO –
Können Sie einen dann vorschlagen? :) – justHelloWorld
wie sollte ich vorschlagen, da ich nicht weiß, was ist Ihr Problem überhaupt. –