2013-05-26 14 views
7

Il seguente codice si compila bene con gcc e clang.Perché questi sovraccarichi non sono ambigui?

template <typename T> 
struct identity 
{ 
    typedef T type; 
}; 

template <typename T> 
void foo(typename identity<T>::type); 

template <typename T> 
void foo(T); 

int main() 
{ 
    foo<int>(0); 
} 

Sembra che la risoluzione di sovraccarico è la scelta del primo overload (il identity<T>::type uno).

Qualcuno potrebbe spiegare perché i sovraccarichi non sono ambigui? Per quanto ne so, l'unica differenza tra loro è che l'argomento del primo è un contesto non dedotto e l'argomento del secondo non lo è, ma dal momento che sto fornendo esplicitamente l'argomento del template, capisco perché dovrebbe essere importante.

+0

Interessante. Ovviamente la seconda funzione sarebbe stata scelta se aveste abilitato la deduzione di tipo non istanziando esplicitamente 'pippo (0)' ma 'pippo (0)' invece (Nessuna deduzione di tipo per la funzione meta identit)[email protected] Prowl: Non voglio mettere in dubbio la tua risposta, fai notare che il tuo ragionamento non è così ovvio come potrebbe sembrare. Assegna al parametro foo un valore predefinito e chiama 'foo ()' senza parametro. La tua argomentazione dovrebbe ancora essere applicata, ma ora i sovraccarichi sono davvero ambigui come previsto da HighCommander4. L'istanziazione esplicita dei modelli di funzioni è complicata. –

risposta

7

Entrambi i sovraccarichi sono validi, ma il primo è più specializzato rispetto a quest'ultimo e pertanto viene selezionato dalla risoluzione di sovraccarico.

Per paragrafo 13.3.3/1 della C++ 11 standard alla risoluzione di sovraccarico:

[...] una funzione valida F1 è definita come una funzione migliore di un'altra funzione vitale F2 se per tutti gli argomenti i, ICSi(F1) non è una sequenza di conversione peggio di ICSi(F2), e quindi

- per qualche argomento j, ICSj(F1) è una migliore sequenza di conversione di ICSj(F2), o, se non che,

01.235.164,106 mila

- il contesto è un'inizializzazione per conversione definita dall'utente (vedere 8.5, 13.3.1.5 e 13.3.1.6) e la sequenza di conversione standard dal tipo di ritorno di F1 al tipo di destinazione (ovvero, il tipo di entità inizializzata) è una sequenza di conversione migliore rispetto alla sequenza di conversione standard da il tipo di ritorno di F2 al tipo di destinazione. [...] o, se non che,

-F1 è una funzione non-modello e F2 è un modello di specializzazione di funzione, o, se non che,

- F1 e F2 sono funzione specializzazioni template e il modello di funzione per F1 è più specializzato rispetto al modello per F2 in base alle regole di ordinamento parziale descritte in 14.5.6.2.

Il processo di determinare quale dei due modelli di funzione è più specializzata rispetto l'altro è delineato nel paragrafo 14.5.6.2/2:

parziale Seleziona ordinamento quale dei due modelli di funzione è più specializzata rispetto l'altro trasformando ciascun modello a sua volta (vedere il prossimo paragrafo) ed eseguendo la deduzione degli argomenti del modello utilizzando la funzione . Il processo di detrazione determina se uno dei modelli è più specializzato dell'altro. Se così, il modello più specializzato è quello scelto dal processo di ordinazione parziale.

+0

Ha senso, grazie! (Ho pensato intuitivamente a "più specializzato di" come significato "si applica a un insieme più piccolo di tipi di input", che è ciò che penso che sia l'intenzione, ma vedo come la definizione tecnica del termine non significhi esattamente questo.) – HighCommander4

+0

@ HighCommander4: Sono contento di averlo aiutato :) La tua intuizione di "si applica a un set più piccolo di tipi di input" ha senso, sebbene - come hai riconosciuto - a volte potrebbe essere fuorviante –

Problemi correlati