클래스 멤버가 같은 이름의 그림자가없는 기능을 함수하는 이유는 무엇입니까?
-
12-12-2019 - |
문제
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
}
};
.
클래스 내부에서 그림자가있는 자유 기능을 부르는 방법을 묻지 않습니다.내가 알고 싶은 것은이 디자인의 이론적 근거가있는 것입니다.
해결책
규정되지 않은 이름 조회의 경우 한 번에 하나의 범위 만 고려되고 그 범위에서 검색 결과가 생성되지 않는 경우 다음으로 향상된 범위가 검색됩니다.귀하의 경우 S
의 범위 만 검색됩니다.
그러나 자유 기능이 다른 서명을 가지고있는 흔한 전화를 금지하는 이유는 다음과 같습니다.
문제는 name lookup 이 이름 이외의 이름 이외의 것으로 나타나지 않으며 식별자 입니다.함수를 호출하려는 사실을 완전히 잊어 버리고 식별자를 볼 수 있습니다.auto x = f;
를 사용하면 동일한 이름 조회가 발생합니다. 그렇게 생각하면 매우 제한된 범위 만 검색 할 수있는 매우 좋은 이유가 있습니다.다른 것은 단지 사용자를 놀라게 할 것입니다.
다른 팁
클래스 멤버 이름 가 이름 조회에서 발견되면 이름 공간 범위가 검색되지 않기 때문에 특별하고 놀라운 규칙이 있지만 매우 놀라운 규칙이 있습니다 (예제에는 적용되지 않습니다).
#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, 이것은 광고입니다.
그러나 자유 기능이 다른 서명을 가지고있는 흔한 전화를 금지하는 이유는 다음과 같습니다.
이름 조회는 오버로드 해상도 전에 발생합니다.
- 조회가 모호한 경우 오버로드 해상도가 완료되지 않습니다.
- 이름 조회에서 실행 가능한 기능이없는 기능이없는 경우 다른 조회가 발견되지 않습니다.
규칙은 과부하 및 이름 조회간에 "피드백"이없는 충분한 복잡한 입니다.나는 단순화를 제안 할 것입니다 (회원을 제거하고 복잡한 이름 공간 범위 이름 규칙을 숨기고 모호한 이름 조회를 제거).
나는 권위있는 답변을 제공 할 수 없습니다 (아마도 Design and Evolution of C++
에서 인용문을 기억하거나 실제로 그 당시위원회에 대한 인용문을 기억할 수도 있습니다). 내 첫 번째 추측은 당신이 보여주는 것처럼 정확하게 실패하는 것입니다.특정 시간에 얼마나 많은 것들이 얼마나 많은 것들이 있는지 잊지 않습니다.추가로 과부하 해상도는 매우 복잡 할 수 있으며 기본 인수와 변환이 가능합니다.그래서 나는 그 경우에 항상 정확히 무엇이 부름을 받는지 항상 확실히 확신 할 수있는 가장 한정된 범위를 갖고 싶습니다.