2014-04-11 11 views
6

La versione del modello viene utilizzata dal compilatore per calcolare t = max(a, b) e max(t, c). Qualunque citazione dallo Standard a sostegno di questo è la benvenuta.Perché la versione del modello viene scelta di seguito dal compilatore?

#include <iostream> 

template <typename T> 
inline T const& max (T const& a, T const& b) 
{ 
    std::cout << "template" << '\n'; 
    return a < b ? b : a; 
} 

template <typename T> 
inline T const& max (T const& a, T const& b, T const& c) 
{ 
    return max (max(a,b), c); 
} 

inline int const& max (int const& a, int const& b) 
{ 
    std::cout << "non-template" << '\n'; 
    return a <b ? b : a; 
} 

int main() 
{ 
    std::cout << max(3, 5, 7) << '\n'; 
} 

The code prints

template 
template 
7 
+1

Provate avanti dichiarando 'int const & max (int const & a, int const & b)' prima del vostro argomento di 3 argomenti 'max'? – Yakk

+0

@Yakk So che questo risolverà il problema. Ma voglio sapere perché è questo? – Alexander

+0

I sovraccarichi dopo il punto della definizione di 'template' vengono trovati solo tramite ADL dallo standard. 'int' non è un tipo definito dall'utente, quindi la tua ADL non funziona (non so come funziona ADL di tipo non definito dall'utente se funziona, onestamente). Alcuni compilatori ** cough ** visual studio ** cough ** non lo fanno correttamente (non sono sicuro del 2013). – Yakk

risposta

8

La definizione della vostra versione non-modello di max() non è visibile presso il call-site, è definito in seguito. Spostare la funzione sopra l'argomento 3 max() o aggiungere un prototipo sopra il sito di chiamata.

int const& max (int const& a, int const& b); 

Ora la versione non modello è stata scelta in entrambi i casi.

Live example


Per quanto riguarda il motivo per cui questo è il caso, credo §3.4.1/1 [basic.lookup.unqual] detiene la risposta.

In tutti i casi elencati in 3.4.1, gli ambiti vengono ricercati in una dichiarazione nell'ordine elencato in ciascuna delle rispettive categorie; la ricerca del nome termina non appena viene trovata una dichiarazione per il nome. Se non viene trovata alcuna dichiarazione, il programma è mal formato.

Nota che l'argomento-dipendente ricerca del nome non si applica nel tuo caso dal momento che gli argomenti per max sono int, e non un tipo definito dall'utente. Viene applicata solo la ricerca del nome non qualificato, quindi, come indicato sopra, la ricerca si interrompe quando viene trovata la prima corrispondenza (la versione del modello di funzione di max()).

L'ultima frase nella sezione citata spiega anche perché se si commenta la versione del modello di funzione di max() il codice non verrà compilato.

+0

@TonyD Questo è corretto, tuttavia, poiché i tipi primitivi non hanno spazi dei nomi, non ci sono spazi dei nomi per ADL da cercare. – Oktalist

+0

C'è qualche spiegazione sul perché ADL non dovrebbe essere applicata a 'int's? Ho intenzione di indovinare che non si applica anche ad altri tipi di built-in. –

Problemi correlati