Il motivo per cui l'hanno reso difficile è perché è pericoloso. È necessario GARANTIRE che nessuno dei membri std::string
con chiave disattivata non cambierà mai valore, o l'intera mappa non sarà più valida. Interessante, la prima soluzione che mi viene in mente sembra follemente hacker, e sembra come UB, ma credo che scrupolosamente segua l'UB.
struct key_type {
mutable const char* ptr;
};
bool operator<(const key_type& lhs, const key_type& rhs)
{return strcmp(lhs.ptr, rhs.ptr)<0;}
struct person {
std::string name;
int age;
};
person& people_map_get(std::map<key_type, person>& map, const char* name) {
auto it = map.insert(name, person{name}).first; //grab, possibly insert
if->first.ptr = it->second.name.c_str(); //in case of insert, fix ptr
return it->second;
}
person& people_map_assign(std::map<key_type, person>& map, person p) {
auto pair = map.insert(name, p); //grab, possibly insert
auto it = pair.first;
if (pair.second == false)
it->second = std::move(p);
if->first.ptr = it->second.name.c_str(); //ptr probably invalidated, so update it
return it->second;
}
int main() {
std::map<key_type, person> people;
people_map_assign(people, person{"ted"});
person frank = people_map_get(people, "frank");
}
Come spero sia chiaro, questo è pazzo vicino al UB, e molto non è raccomandato. Fondamentalmente, durante un insert/find, i punti chiave sul tuo oggetto temporaneo o sulla stringa di input, e quindi non appena l'oggetto viene inserito/trovato, la chiave viene cambiata in modo che punti al valore contenuto nel membro della stringa, e fino a quando non fai mai nulla che invalida il valore di ritorno di .c_str()
su qualsiasi oggetto person
contenuto, tutto funziona a malapena. Credo.
fonte
2013-08-28 20:12:51
Come usare un 'std :: set' dove 'C' confronta la stringa memorizzata in' T'? –
@Daniel: Ma poi avrei bisogno di fornire un intero oggetto 'T' per la ricerca, e non solo un' std :: string', giusto? Oppure 'C' può essere sovraccarico per confrontare' T' con 'T' e anche' T' per 'std :: string'? –
Ah, vedo che C++ 14 aggiungerà un membro 'find' basato su template per cercare su qualsiasi tipo che possa comparare con' T'. –