2012-08-08 9 views
9

아래의 C++ 코드에서 double 매개 변수에 대해 foobar이 먼저 정의되고 Foo 유형의 단일 매개 변수에 대해 다시 정의됩니다. 둘 다 전역 이름 공간 내에서 정의됩니다. one 네임 스페이스에 다른 네임 스페이스 내에서 C++ 전역 네임 스페이스 액세스

foobar의 또 과부하 형 Bar 단일 파라미터로 정의된다. foobar의이 버전에서 double 인수 (42.0)를 사용하는 foobar에 대한 규정되지 않은 호출은 실패합니다. foobar에 대한 비슷한 호출은 double 인수와 함께 (: :) 범위 해결 연산자로 정규화 된 이번 경우에도 성공합니다.

한편 foobar에 대한 규정되지 않은 호출은 Foo 유형의 인수와 함께 성공합니다. 범위 분석 연산자로 규정 된 에 Foo 인수가있는 호출도 성공합니다.

왜 두 시나리오가 다르게 동작합니까? gcc 4.7과 clang ++ 3.2를 모두 사용합니다.

struct Foo {}; 
struct Bar {}; 

double foobar(double x) { return x; } 
Foo foobar(Foo f) { return f; } 

namespace one { 

    Bar foobar(Bar b) { 
    //foobar(42.0); // error: can't convert to Bar 
    ::foobar(42.0); 

    Foo f; 
     foobar(f); // no problem 
    ::foobar(f); 
    return b; 
    } 
}; 

답변

8

Argument dependent lookup.

foobar(f)의 호출에서 Foo의 네임 스페이스의 함수가 고려됩니다.

double에 대해서는 해당 유형이 임의의 네임 스페이스에서 선언되지 않았기 때문에 작동하지 않습니다.

+0

마지막 문장에 추가 : 정규화되지 않은 이름 조회는 일치하는 * 이름 *을 찾으면 바로 중지합니다. 먼저 로컬 범위를 고려하여 이름을 찾지 않는 경우에만 상위 및 전역 범위를 검색합니다 . – Xeo

+0

감사합니다. Bo. ADL에 대한 링크를 통해 명확하게 알 수 있습니다. – user2023370

+0

@Xeo :'foobar (bar)'를 찾으면'foobar (f) '에 대한 호출이 실패한다는 것을 의미하지 않을까요? – user2023370