Sto sviluppando una libreria (C++) che utilizza contenitori non ordinati. Questi richiedono un hasher (di solito una specializzazione della struttura modello std::hash
) per i tipi di elementi che memorizzano. Nel mio caso, quegli elementi sono classi che racchiudono stringhe letterali, simili a conststr
dell'esempio allo the bottom of this page. STL offre una specializzazione per i puntatori char costanti, che, tuttavia, calcola solo puntatori, come spiegato here, in the 'Notes' section:Verificare se i letterali di stringa uguale sono memorizzati allo stesso indirizzo
Non c'è specializzazione per stringhe C.
std::hash<const char*>
produce un hash del valore del puntatore (l'indirizzo di memoria), esso non esamina il contenuto di alcun array di caratteri.
Anche se questo è molto veloce (o almeno così credo), non è garantito dalla norma se diversi letterali uguali stringa sono memorizzati nello stesso indirizzo C++, come spiegato in this question. Se non lo sono, la prima condizione di hashers non sarebbe soddisfatto:
Per due parametri k1 e k2 che sono uguali,
std::hash<Key>()(k1) == std::hash<Key>()(k2)
desidero calcolare selettivamente l'hash utilizzando la fornito specializzazione, se la garanzia di cui sopra è data, o qualche altro algoritmo in caso contrario. Sebbene ricorrere alla richiesta di coloro che includono le mie intestazioni o di costruire la mia libreria per definire una particolare macro sia fattibile, una implementazione definita sarebbe preferibile.
C'è qualche macro, in qualsiasi implementazione C++, ma principalmente g ++ e clang, la cui definizione garantisce che diversi valori letterali di stringa uguale siano memorizzati nello stesso indirizzo?
Un esempio:
#ifdef __GXX_SAME_STRING_LITERALS_SAME_ADDRESS__
const char str1[] = "abc";
const char str2[] = "abc";
assert(str1 == str2);
#endif
Certamente no, perché non si tratta solo di "* stringhe uguali memorizzate nello stesso indirizzo *", ma più stringhe memorizzate come sottostringhe di una stringa più grande, ecc. Ad esempio, dati due letterali '" mondo "' e '" ciao mondo "', il compilatore può generare codice come '.data: byte STR {h, e, l, l, o,, w, o, r, l, d}' facendo riferimento al primo come 'STR + 6' e il secondo come 'STR'. – Manu343726
Anche se i valori letterali di stringa sono coalizzati, due variabili 'char []' non saranno. 'st1 == str2' non sarà mai vero. –
Non puoi usare 'std :: string' per il tuo contenitore?O matrici di carbone? – quantdev