태그 보관물: qualified-name

qualified-name

Derived1 :: Base와 Derived2 :: Base가 동일한 유형을 참조합니까? 및 GCC는이 코드에 동의하지 않습니다. struct Base {

MSVC, Clang 및 GCC는이 코드에 동의하지 않습니다.

struct Base { int x; };
struct Der1 : public  Base {};
struct Der2 : public  Base {};

struct AllDer : public Der1, public Der2 {
    void foo() {
        Der1::Base::x = 5;
    }
};

Godbolt

GCC :

<source>: In member function 'void AllDer::foo()':
<source>:10:21: error: 'Base' is an ambiguous base of 'AllDer'
   10 |         Der1::Base::x = 5;
      |                     ^
Compiler returned: 1

Clang은 비슷한 오류를 제공하고 MSVC는 오류를 제공하지 않습니다.

여기 누구세요?

나는 이것이 [class.member.lookup]에 포함되어 있다고 생각 하지만,이 사건에 대해 무엇을 말하려고하는지 이해하는 데 어려움이 있습니다. 관련 부분을 인용하고 가능한 경우 일반 영어로 설명하십시오.

추신 :이 질문에서 영감을 얻은 이유 :: :: 연산자 trough 파생 클래스에서 기본 클래스에 대한 참조가 모호한 이유는 무엇입니까?

PPS : 실제로 내 의심은 Der1::Base유형을 나타내는 지, Base그리고 Der2::Base정확히 동일한 유형인지 또는 하위 객체를 나타내는 지 여부입니다. 나는 그것이 첫 번째라고 확신하지만, 후자라면 MSVC가 옳을 것입니다.



답변

제목에 질문에 대답하기 위해, 예, Derived1::Base참조합니다 주입-클래스 이름 [class.pre] Base 지금과는 않습니다 Derived2::Base. 둘 다 클래스를 참조하십시오 ::Base.

이제 정적 멤버 Base가 있으면 조회 가 명확합니다. 하나만 있습니다.xBase::x

이 예에서의 문제점은이 x비 고정 부재이며 AllDer갖는 이러한 부재. 멤버 가 하나만 x있는 모호하지 않은 기본 클래스를 지정하여 이러한 액세스를 명확하게 할 수 있습니다 . 모호하지 않은 기본 클래스이며 멤버 가 하나 이므로 두 멤버 중 의미하는 것을 명확하게 지정합니다 . 멤버 도 하나 뿐이지 만의 모호한 기초는 아닙니다 . 의 모든 인스턴스 에는 유형의 하위 객체가 두 개 있습니다. 따라서 귀하의 예에서는 모호합니다. 그리고 또 다른 이름 이기 때문에AllDerxDerived1xDerived1::xxAllDerBasexAllDerAllDerBaseBase::xDerived1::BaseBase 모호합니다.

[class.member.lookup] x은 nested-name-specifier의 컨텍스트에서 조회되도록 지정하므로 먼저 해결해야합니다. 우리는 참으로 찾고 있습니다 Base::x하지, Derived1::x우리가 해결하여 시작했기 때문에, Derived1::BaseBase. 이 부분은 단 하나있다, 성공 xBase.주 (12)가 명시 적으로 명확한 이름 조회를 사용하여 아직도 그 같은 이름을 가진 여러 하위 객체가있을 때 실패 할 수 있음을 알려줍니다 [class.member.lookup]에. D::i이 예에서 기본적으로 당신 Base::x입니다.


답변

클래스 이름을 클래스의 멤버로 참조 할 수있는 이유는 cpp using Base = ::Base;가 Base에 작성한 것처럼 편리하게 사용할 수 있도록 cpp의 별칭을 지정하기 때문 입니다.
직면 한 문제 Der1::BaseBase입니다.
따라서 쓸 때 Der1::Base::x와 동일합니다 Base::x.


답변