Visual C++ 2012. 코드. 나는 그것이 컴파일되어야한다고 생각한다; 컴파일러는 정중하게 동의하지 않습니다. 아래로 범위를 좁혔습니다.VC++ 2012에서 예기치 않게 모호한 오버로드 해결
struct B { };
void foo(B* b, signed int si) { } // Overload 1
void foo(B const* b, unsigned int ui) { } // Overload 2
int main()
{
B b;
unsigned int ui;
foo(&b, ui);
}
그래서 과부하 해결을위한 후보가 두 가지 있습니다. 첫 번째 오버로드의 경우 첫 번째 인수는 정확히 일치하고 두 번째 인수는 정수 변환 (부호가없는 부호가있는)이 필요합니다. 두 번째 오버로드의 경우 두 번째 인수가 정확히 일치하고 첫 번째 인수는 cv 조정이 필요합니다 (&b
은 비 const에 대한 포인터이기 때문에).
이제 완전히 모호한 것으로 보입니다. 오버로드 1의 경우 첫 번째 인수는 과부하 해결에 대한 표준 섹션에서 정의한 "완전 일치"이지만 두 번째 인수는 "변환"입니다. 오버로드 2의 경우 두 인수가 모두 "완전 일치"입니다 (자격 변환은 동일성 순위와 동일 함). 따라서 (내 명백하게 불완전한 추론이 진행됩니다.) 과부하 2는 모호성없이 선택되어야합니다. 그리고 아직 :
a.cpp(12): error C2666: 'foo' : 2 overloads have similar conversions
a.cpp(6): could be 'void foo(const B *,unsigned int)'
a.cpp(5): or 'void foo(B *,int)'
while trying to match the argument list '(B *, unsigned int)'
note: qualification adjustment (const/volatile) may be causing the ambiguity
GCC는 기본 언어와 C++ 11 (감사합니다, IDEOne!) 모두에서 코드와 잘 어울립니다. 그래서 저는 MSVC의 버그에 대해이 글을 쓰는 경향이 있습니다. 그러나 (a) 여러분은 자신의 버그가 컴파일러 버그라고 생각하는 사람들에 대해 무엇을 말하는지 알 것입니다. (b) 이것은 꽤 명백한 버그 일 것입니다. , 적합성 테스트 중에 적색 플래그를 보냈을 것입니다.
이 메시지는 비 호환 MSVC입니까, 아니면 비 호환 GCC입니까? (또는 둘 다?) 과부하 해결 소리에 관한 나의 추론은 무엇입니까?
어떤 컴파일러가 정확한지 모르겠지만 인간으로서 나는 두 가지 유형의 변환의 우선 순위에 따라 명확성을 제거하지 않고 어떤 오버로드가 사용되는지 알고 싶어합니다 .-) – Cameron
@Cameron Oh, I 동의하다. 실제 유스 케이스는 훨씬 더 의미가 있으며, 실제로 * 보이는 * 모호하지 않습니다. – Sneftel