7

It recently came to my attention 해당 구성원 함수 완전 그림자 클래스 내부에서 동일한 이름의 자유 함수입니다. 그리고 완전히 동일한 이름을 가진 모든 자유 함수가 과부하 해결을 위해 고려되지 않는다는 것을 완전히 의미합니다. 나는이 같은 somwthing 함께 할 왜 이해할 수 :클래스 멤버가 동일한 이름의 그림자없는 함수를 사용하는 이유는 무엇입니까?

기능이 동일한 서명이
void f(); 

struct S 
{ 
    void f(); 

    void g() 
    { 
     f(); // calls S::f instead of ::f 
    } 
}; 

, 변수 범위 지정 등의 천연 같은 방식으로 작동합니다. 나는 클래스 내부에서 무료 기능을 그림자 호출하는 방법을 요구하고 있지 않다

void f(); 

struct S 
{ 
    void f(int x); 

    void g() 
    { 
     f(); // fails to compile attempting to call S::f, which has wrong signature 
    } 
}; 

: 무료 기능이 같은 다른 서명이있는 경우 왜 UNAMBIGIOUS 통화를 금지하고 있습니다. 내가 알고 싶은 것은이 디자인의 근거입니다.

+1

Bjarne Stroustrup에게 문의해야 할 수도 있습니다. – peacemaker

+1

이렇게 검색하면 생성 된 후보 함수의 목록이 항상 작음을 의미합니다. 그것은 컴파일 시간에 유용합니다. 가능한 모든 후보 (ADL 포함)를 검색했는지 상상할 수 있습니다. 많은 템플릿이 있으면 매우 빨리 느려질 것입니다. 또한 대부분의 경우 사용법과 원하는 의미를 반영합니다. 보통'foo'라고 말할 때'foo'가 가장 가까운 것으로 생각합니다. 가장 가까운 것이 아닌 경우 실수를 저 지르려고합니다. 런타임에 이상한 일이 발생하는 것보다 오류가 낫습니다. 일을 지역적으로 유지하는 것은 좋은 행동입니다. – Flexo

+2

이름 조회에서이 프레젠테이션을 즐길 수 있습니다. http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of -n – MFH

답변

6

정규화되지 않은 이름 조회의 경우 한 번에 하나의 범위 만 고려되며 해당 범위의 검색 결과가 나오지 않으면 다음 상위 범위가 검색됩니다. 귀하의 경우 S의 범위 만 검색됩니다.

그러나 무료 기능이 같은 다른 서명이 곳에 왜 UNAMBIGIOUS 통화를 금지 :

문제는 이름 조회는, 이름 만 물체로 식별자 자체를 우려하지 않는다는 것입니다을. 사실 함수를 호출하기를 원한다는 사실을 전혀 모른 채 식별자 만 보입니다. auto x = f;을 사용하면 동일한 이름 검색이 발생합니다. 그런 식으로 생각하면 매우 제한된 범위의 검색 만 원하는 매우 좋은 이유가 있습니다. 다른 것은 그저 사용자를 놀라게 할 것입니다.

+1

"_ 문제는 이름 검색이 이름, 식별자 이외에는 아무런 관련이 없다는 것입니다."거의 모든 언어에서 그렇습니다. C++이 아닙니다. – curiousguy

2

신뢰할 수있는 답변을 제공 할 수 없습니다. (어쩌면 Design and Evolution of C++의 견적을 기억하거나 실제로위원회에 있었을 수도 있습니다.)하지만 내 첫 번째 추측은 표시 할 때 정확히 실패하는 것입니다. 특정 시점에 얼마나 많은 것들이 범위 내에 있는지 잊어 버리는 것은 쉽습니다. 또한 과부하 해결은 매우 복잡 할 수 있으며 기본 인수와 변환이있을 수 있습니다. 그래서 나는 정확히 정확히 무엇이 호출되고 있는지 항상 알기 위해이 경우 가장 제한된 범위를 가질 것입니다.

+0

추측하지만 그건 내 직감이에요. 미친 멀리 검색 한 것과 오타를 구분하는 것은 어렵습니다. – Flexo

+0

"_ 특정 시간에 얼마나 많은 것들이 범위에 있는지 잊어 버리기 쉽습니다 ._"이것은 이름을 숨기지 않는 것에 대한 매우 강력한 주장입니다. – curiousguy

3

특별한, 아주 놀라운 규칙 (그러나 그것은 당신의 예에 적용되지 않습니다)을 클래스 멤버 이름이 이름 검색에 의해 발견되면, 네임 스페이스 범위가 검색되지 않도록 진술이있다 :

#include <string> 

struct C { 
    std::string s; 

    explicit C (std::string); 

    void swap (C& rhs) { 
     swap (s, rhs.s); // error: swap is C::swap 
    } 
}; 

void swap (C& lhs, C& rhs) { 
    swap (lhs.s, rhs.s); // std::swap(string,string) 
} 

IMO, 이건 미친 짓이야.

그러나 무료 기능이 같은 다른 서명이 곳에 왜 UNAMBIGIOUS 통화를 금지 :

이름 조회가 과부하를 해결하기 전에 발생합니다 조회가 모호

  • 경우, 해상도를 오버로드하는 것은 수행되지 않습니다.
  • 이름 조회에서 실행 가능 기능을 찾지 못하면 다른 조회 라운드를 시도하지 않습니다.

규칙은 오버로드와 이름 조회 사이에 "피드백"없이 충분히 복잡합니다. 나는 단순화 (멤버를 제거하면 네임 스페이스 범위 이름 규칙을 숨기고 모호한 이름 조회를 제거하는 것)를 제안 할 것입니다.

+0

이것은 생각만큼 미친 것은 아닙니다. 이름 검색은 일치 항목이 발견되면 중지되고 (§3.4 정도의 어딘가에 명시되어 있음) 정확한 순서가 내부에서 바깥쪽으로 제공됩니다. 따라서 이름이있는 멤버가 발견되면 중지됩니다. 놀랄 일이 아닙니다. – Damon

+0

@Damon "두번째'swap' 호출이 보여 주듯이"_ 일치하는 것이 발견되면 _ 이름 검색이 멈춤 _ "하지 않습니다. – curiousguy

관련 문제