Formalmente, quando si confrontano le sequenze di conversione, le trasformazioni di lvalue vengono ignorate. Le conversioni sono raggruppati in diverse categorie, come la regolazione qualificazione (T*
->T const*
), lvalue trasformazione (int[N]
->int*
, void()
->void(*)()
), e altri.
L'unica differenza tra i due candidati è una trasformazione lvalue. I letterali stringa sono array che convertono in puntatori. Il primo candidato accetta la matrice per riferimento e quindi non avrà bisogno di una trasformazione lvalue. Il secondo candidato richiede una trasformazione lvalue.
Quindi, se ci sono due candidati che entrambe le specializzazioni di modelli di funzione sono ugualmente valide guardando solo alle conversioni, la regola è che quella più specializzata viene scelta eseguendo l'ordinamento parziale dei due.
Mettiamo a confronto i due, cercando in loro firma della loro funzione di lista di parametri
void(T const&);
void(T*);
Se scegliamo un certo tipo unico Q
per la prima lista dei parametri e cercare di abbinare contro la seconda lista di parametri, ci sono corrispondenti Q
contro T*
. Ciò fallirà, dal momento che Q
non è un puntatore. Quindi, il secondo è almeno specializzato quanto il primo.
Se facciamo il contrario, corrispondiamo allo Q*
rispetto allo T const&
. Il riferimento viene eliminato e i qualificatori di livello superiore vengono ignorati e il rimanente T
diventa Q*
. Questa è una corrispondenza esatta ai fini dell'ordine parziale, e quindi la deduzione dell'elenco dei parametri trasformati del secondo rispetto al primo candidato ha esito positivo. Poiché l'altra direzione (rispetto alla seconda) non è riuscita, il secondo candidato è più specializzato rispetto al primo - e di conseguenza, la risoluzione di sovraccarico preferirà la seconda, se ci sarebbe altrimenti un'ambiguità.
At 13.3.3.2/3
:
standard sequenza conversione S1 è in una sequenza di conversione di sequenza conversione standard S2 se [...]
- S1 è una corretta sottosequenza di S2 (confrontando le sequenze di conversione in forma canonica definito da 13.3.3.1.1, escludendo qualsiasi trasformazione Ivalue; la sequenza conversione identità è considerata una sottosequenza di eventuali non sequenza -identity conversione) o, se non che [...]
Poi 13.3.3/1
- lascia ICSi (F) denotare la sequenza di conversione implicita che converte l'argomento i-th nella lista al tipo del parametro i-esimo della funzione vitale F. 13.3.3.1 definisce le sequenze di conversione implicite e 13.3.3.2 definisce cosa significa che una sequenza di conversione implicita deve essere una sequenza di conversione migliore o una sequenza di conversione peggiore di un'altra.
Date queste definizioni, una funzione F1 vitale è definito come una funzione migliore di un'altra funzione F2 valida se per tutti gli argomenti i, ICSI (F1) non è una sequenza di conversione peggio ICSI (F2), e poi [...]
- F1 e F2 sono specializzazioni funzione di modello, e il modello di funzione F1 se non è più specializzata rispetto al modello per F2 secondo le regole di ordinamento parziali descritto in 14.5.5.2, o che , [...]
Infine, ecco la tabella delle conversioni implicite che possono partecipare a una sequenza di conversione standard a 13.3.3.1.1/3
.
Conversion sequences http://img259.imageshack.us/img259/851/convs.png
Divertente, MSVC9 chiama la funzione "foo" nei simboli di debug, ma - apparentemente poiché riconosce che l'implementazione è identica - utilizza la stessa implementazione per entrambe le chiamate. - Interessante domanda, comunque. –
peterchen
AFAIK VC piega le istanze del modello che generano un codice identico. – sbi
GCC (4.2.4) esegue sia le istanze sia le istanze fino a -O3, dove le elude completamente per queste implementazioni e la rende in linea. –