17

Mentre giocavo con riferimenti universali, mi sono imbattuto in questa istanza in cui clang e gcc non sono d'accordo sulla risoluzione di sovraccarico.Un argomento lvalue preferisce un parametro di riferimento lvalue su un riferimento universale?

#include <iostream> 

struct foo {}; 

template<typename T> 
void bar(T&) { std::cout << "void bar(T&)\n"; } 

template<typename T> 
void bar(T&&) { std::cout << "void bar(T&&)\n"; } 

int main() 
{ 
    foo f; 
    bar(f); // ambiguous on gcc, ok on clang 
} 

gcc reports la chiamata sopra è ambigua. Tuttavia, clang seleziona l'overload T& e viene compilato correttamente.

Quale compilatore è sbagliato e perché?

Modifica:
Testato lo stesso codice su VS2013 Preview, e concorda con clang; ad eccezione di Intellisense, che è sul lato gcc :-)

+5

Questo è [GCC bug 54425] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425). – Casey

+0

Anche i compilatori intel (13.0.1) e pgi (13.4) generano un errore al riguardo. – Zulan

risposta

18

Il "riferimento universale" deduce il parametro su foo&. Il primo modello deduce anche il parametro su foo&.

C++ ha una regola di ordinazione parziale per i modelli di funzione che rende T& più specializzato di T&&. Quindi il primo modello deve essere scelto nel codice di esempio.

+1

Quindi vuol dire che gcc è sbagliato? –

+6

@DrewMcGowen sì – Yakk

+4

Trovato il riferimento standard - dalla sezione N3691 §14.8.2.4/9 – Praetorian

Problemi correlati