17

Während ich mit universellen Referenzen spielte, stieß ich auf diese Instanz, bei der clang und gcc bei der Überladungsauflösung nicht übereinstimmen.Begünstigt ein lvalue-Argument einen Lvalue-Referenzparameter gegenüber einer universellen Referenz?

#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 Der obige Aufruf ist nicht eindeutig. clang wählt jedoch die T& Überladung und kompiliert erfolgreich.

Welcher Compiler ist falsch und warum?

Bearbeiten:
Getestet den gleichen Code auf VS2013 Preview, und es stimmt mit clang überein; außer Intellisense, die auf der Seite von gcc ist :-)

+5

Dies ist [GCC-Fehler 54425] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425). – Casey

+0

Beide Intel (13.0.1) und Pgi (13.4) Compiler liefern auch einen Fehler darüber. – Zulan

Antwort

18

Die "universelle Referenz" leitet den Parameter auf foo&. Die erste Vorlage leitet auch den Parameter zu foo&.

C++ hat eine Teilordnungsregel für Funktionsvorlagen, die T& spezialisierter als T&& macht. Daher muss die erste Vorlage in Ihrem Beispielcode ausgewählt werden.

+1

Also heißt das gcc ist falsch? –

+6

@DrewMcGowen ja – Yakk

+4

Gefunden die Standardreferenz - von N3691 Abschnitt §14.8.2.4/9 – Praetorian