2011-12-30 21 views
14

Secondo cplusplus.com, la funzione std::type_info::before() ...A cosa serve `tipo_info :: before`?

Restituisce vero se il tipo precede il tipo di RHS nell'ordine collazione.
L'ordine di confronto è solo un ordine interno mantenuto da una particolare implementazione e non è necessariamente correlato ai rapporti di eredità o all'ordine di dichiarazione.

Quindi, a cosa serve?

risposta

24

Si consideri che si desidera mettere gli oggetti type_info come chiavi in ​​un map<type_info*, value>. Lo type_info non ha un operator < definito, quindi è necessario fornire il proprio comparatore. L'unica cosa che è garantito per funzionare dall'interfaccia type_info è la funzione before(), poiché né gli indirizzi dei type_info né la name() devono essere univoci:

struct compare { 
    bool operator()(const type_info* a, const type_info* b) const { 
     return a->before(*b); 
    } 
}; 

std::map<const type_info*, std::string, compare> m; 

void f() { 
    m[&typeid(int)] = "Hello world"; 
} 
+1

"* Il' type_info' non ha un 'operatore <' definito, quindi è necessario fornire il proprio comparatore. * "' Std :: less <> '(' std :: map <> 'predefinito comparatore) funziona per ** tutti ** i puntatori, si ottiene semplicemente l'ordinamento dell'indirizzo anziché l'ordinamento di collation. – ildjarn

+6

@ildjarn: hai frainteso il problema. Lo standard non garantisce che al massimo esista un 'type_info' per tipo. Infatti è comune incontrare * più di un 'typeinfo' * creato per lo stesso tipo. Il caso più banale è nel contesto di librerie con collegamenti dinamici, come ha detto Dietmar. – ybungalobill

+1

@ildjarn Rileggere il tuo preventivo. Parla di 'operator <' di 'type_info', ma si discute sulla validità del confronto dei puntatori a' type_info', il che implica che la frase citata è in qualche modo sbagliata. Ma non lo è, perché non ho detto nulla sul confronto dei puntatori. Allora perché la gente scrive commenti irrilevanti? – ybungalobill

1

Fornisce un ordine.

Ciò è necessario se si desidera memorizzare valori in alcuni contenitori, come std :: map.

4

Questo è utile per definire un ordine typeinfo oggetti, ad esempio per metterli in una std :: map. L'ovvia domanda di follow-up è: perché non è scritto l'operatore <()? Non conosco la risposta a questa domanda.

+2

"* L'ovvia domanda di follow-up è: perché non è scritto operatore <()? *" Come si definisce un operatore <'per un tipo di puntatore? – ildjarn

+0

'type_info' non ha un costruttore di copia o un operatore di copia-assegnazione, quindi non può essere memorizzato direttamente in un contenitore. E, naturalmente, il tipo di chiave di un contenitore associativo non può essere un riferimento, quindi l'unica opzione rimanente è di memorizzare un 'type_info *', per il quale non si può fornire un 'operatore <'. Forse la cosa più sensata da fare è specializzare 'std :: less '. – ildjarn

+1

@ildjarn: La domanda di Dietmar è "perché' type_info' ha 'before()' ma non 'operator <' '.Anche se quello che dici è corretto, non risponde alla sua domanda. Per esempio. perché non posso scrivere 'typeid (int) ybungalobill

1

Pensate a un operatore minore di (<) per gli oggetti type_info. Se hai mai voluto memorizzare nella raccolta ordinata - un tale insieme di mappe - puoi usarlo per creare un comparatore appropriato. È un metodo affidabile e preferibile, al contrario, ad esempio, utilizzando il nome del tipo che potrebbe non essere univoco.