다음 코드가 있습니다.
namespace A {
struct Foo {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo {
Bar(Foo foo) {
c = foo.b;
}
int c;
};
A :: Foo에는 b라는 멤버가 없으므로 C ++ 컴파일러는 “c = foo.b”에서 불평합니다. :: Foo로 Bar 매개 변수의 유형을 변경하면 작동합니다.
내 질문은이 동작의 합리적인 이유입니다 (상속이 Bar가 A 네임 스페이스에 들어가게한다는 사실과 관련이 있다고 생각하지만이 이론을 뒷받침하는 문서를 찾을 수는 없습니다.
답변
모든 수업은 회원으로 이름이 주입되어 있습니다. 이름을 지정할 수 있습니다 A::Foo::Foo
. 이것을 주입 된 클래스 이름이라고합니다.
[수업]
2 class-name은 class-name이 표시된 직후 선언되는 범위에 삽입됩니다. class-name은 클래스 자체의 범위에도 삽입됩니다. 이것을 injection-class-name이라고합니다. 액세스 확인을 위해 주입 된 클래스 이름은 마치 공용 멤버 이름 인 것처럼 처리됩니다.
[basic.lookup]
3 클래스의 삽입 클래스 이름은 이름 숨기기 및 조회를 위해 해당 클래스의 멤버로 간주됩니다.
인수 유형의 규정되지 않은 이름 검색은 클래스의 범위에서 시작 Bar
하므로 해당 클래스의 멤버를 설명하기 위해 기본 클래스의 범위로 계속 진행됩니다. 그리고 A::Foo::Foo
유형 이름으로 찾을 수 있습니다.
글로벌 유형 이름을 사용하려면 주변 (글로벌) 네임 스페이스로 이름을 규정하십시오.
Bar(::Foo foo) {
c = foo.b;
}
주입 된 클래스 이름이 표시되지 않는 범위에서 정규화 된 조회를 수행하는 것입니다.
후속 “이유”질문에 대해서는
답변
완전한 답변 Bar
은 아니며 ( 컴파일 이후)를 입력하지 않는 코드 만 표시 합니다 namespace A
. 상속 할 때 A::Foo1
모호함에 대한 문제는 없음을 알 수 있습니다.Foo
이 다른 수 Bar
있습니다 A
.
namespace A {
struct Foo {
int a;
};
struct Foo1 {
int a;
};
}
struct Foo {
int b;
};
struct Bar : public A::Foo1 {
Bar(Foo foo) {
c = foo.b;
}
int c;
};