17

범용 참조를 가지고 노는 동안, clang과 gcc가 과부하 해결에 동의하지 않는이 인스턴스를 발견했습니다.lvalue 인수는 범용 참조보다 lvalue 참조 매개 변수를 선호합니까?

#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 위의 호출은 모호합니다. 그러나 clangT& 오버로드를 선택하고 성공적으로 컴파일합니다.

어떤 컴파일러가 잘못 되었습니까? 그 이유는 무엇입니까?

편집 :
VS2013 미리보기에서 동일한 코드가 테스트되었으며 clang과 일치합니다. gcc쪽에있는 Intellisense 제외 :-)

+5

[GCC 버그 54425] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425)입니다. – Casey

+0

intel (13.0.1)과 pgi (13.4) 컴파일러는 모두 오류를 발생시킵니다. – Zulan

답변

18

"universal reference"는 매개 변수를 foo&으로 추론합니다. 첫 번째 템플릿은 또한 매개 변수를 foo&으로 추론합니다.

C++에는 T&T&&보다 특수화되도록 기능 템플릿에 대한 부분 정렬 규칙이 있습니다. 따라서 첫 번째 템플릿을 예제 코드에서 선택해야합니다.

+1

그렇다면 gcc가 잘못되었다는 의미입니까? –

+6

@DrewMcGowen 예 – Yakk

+4

N3691 섹션 §14.8.2.4/9의 표준 참조를 찾았습니다. – Praetorian