17

Podczas odtwarzania z odniesieniami uniwersalnymi natknąłem się na to wystąpienie, w którym klang i gcc nie zgadzają się w kwestii rozdzielczości przeciążenia.Czy argument lwartość preferuje parametr odniesienia lwartość nad odwołaniem uniwersalnym?

#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 powyższe połączenie jest niejednoznaczne. Jednak clang wybiera przeciążenie i kompiluje pomyślnie.

Który kompilator jest nieprawidłowy i dlaczego?

Edytuj:
Testowany ten sam kod w podglądzie VS2013 i zgadza się z klangiem; z wyjątkiem Intellisense, który znajduje się po stronie gcc :-)

+5

To jest [błąd GCC 54425] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425). – Casey

+0

Zarówno kompilatory intel (13.0.1), jak i pgi (13.4) również dają o tym błąd. – Zulan

Odpowiedz

18

"Uniwersalny odnośnik" dedukuje parametr do foo&. Pierwszy szablon uwzględnia także parametr foo&.

C++ ma częściową regułę porządkowania szablonów funkcji, która czyni bardziej wyspecjalizowaną niż T&&. W związku z tym pierwszy szablon musi zostać wybrany w przykładowym kodzie.

+1

Czy to oznacza, że ​​gcc jest nieprawidłowy? –

+6

@DrewMcGowen yes – Yakk

+4

Znaleziono standardowe odniesienie - od N3691 sekcja § 14.8.2.4/9 – Praetorian

Powiązane problemy