Mi piacerebbe condividere un approccio che ha funzionato per me in passato:
struct Thing {
std::string const property; // This is an important assumption
int dummy;
};
Voglio fare riferimento al property
delle cose, quindi uso std::reference_wrapper
. Supponendo che la ricerca avvenga molto più spesso che cambiando le cose, memorizzerei le cose in un std::vector
. Per ottenere una rapida ricerca, utilizzerei una mappa dai riferimenti alle proprietà ai riferimenti alle cose.
std::vector<Thing> things;
std::map<
std::reference_wrapper<std::string const>,
std::reference_wrapper<Thing>> lookup;
Effettuare una ricerca è semplice, data una stringa p
:
Thing & i_want = lookup.at(p).get();
L'inserimento delle cose deve occuparsi di riferimenti eventualmente invalidati:
// Thing newcomer
auto old_capacity = things.capacity();
things.push_back(newcomer); // or emplace
if (old_capacity == things.capacity()) {
lookup.emplace(
std::ref(things.back().property),
std::ref(things.back()));
} else {
lookup.clear();
for (auto const & t : things) {
lookup.emplace(
std::ref(t.property), std::ref(t));
}
}
Rimuovere le cose è lasciato come esercizio al lettore. L'utilizzo di una struttura dati diversa rispetto a un vettore come archiviazione di supporto può essere preferibile se l'aggiunta o la rimozione di cose avviene più spesso.
Si noti che il codice sopra riportato è solo un abbozzo dell'idea. Sono sul mio cellulare, dove è piuttosto difficile scriverlo e testarlo.