26

다음 코드사용하여 선언의 이상한 행동은

struct A { using type = int; }; 
struct B : private A {}; 
struct C : B { using base_type = A; }; 

GCC 6.1의 모든, 3.8 연타를 참조하십시오, 그리고 AC 내부 보조의 이름부터 아니므로 MSVC 2015 업데이트 3이 컴파일 거부 A은 (는) B의 비공개 기초입니다. gcc가 을 using base_type = A에 넣으면 A의 기본 생성자를 참조합니다. msvc와 clang은 그렇지 않습니다.

는 아마도 컴파일 오류로 인해 상속에 의해 트리거 이름의 주입,하지만 난이 이상한 오류가 표준의 말씀 인 경우 알고 싶어 ( using base_type = ::Ausing base_type = A 모든 컴파일러가 잘 작동하게 수정 때문에). I가 알 수있는 바와 같이, A::type 좋아하지

보다 구체적

  1. A 단지 클래스 이름이다 (비록 함수 이름 GCC 오인하여) C하지 내부AB에 도입된다. 이 이름이 B에 비공개로 간주되는 이유는 무엇입니까?
  2. 이 컴파일 오류는 버그로 간주 되나요? 아니면 표준 사양에서 뚜렷하지 않습니까?
+1

나는 이것이'C '내부의'A'에 대한 이름 검색이 어떻게 작동하는지에 달려 있다고 생각합니다.먼저'using '전에'C'의 범위에서'A'라는 이름으로 선언 된 것이 있는지 검사합니다. 하나도 찾지 못하기 때문에 Base 클래스이므로'B'의 범위에서 검사합니다. 그리고'B' 범위에서'A'를 찾지 못하면'global namespace'에서 조망 할 것입니다. 그러나 어떻게 든'B'에 의한'A'의 '사적 상속'은 두 번째 룩업, 즉'B'의 범위 내에서 멈추고 있습니다. 'fully qualified'라는 이름으로 작동하기 때문에 실제 문제는 같은 줄에 있어야한다고 생각합니다. – Arunmu

+4

http://eel.is/c++draft/class.access.spec#5가 적합합니다. –

+0

@PiotrSkotnicki 감사합니다. 직접 질문에 답변합니다. 그러나이 규칙의 배후에 합리적인 것을 줄 수 있습니까? –

답변

28

unqualified name lookup의 규칙에 따르면

(강조 광산) 규정 화되지 않은 이름에 대한

, 즉 범위 결정 연산자의 오른쪽에 나타나지 않는 이름입니다 :: name lookup은 어떤 종류의 선언이라도 발견 될 때까지 아래에 설명 된대로 범위를 검사합니다. 조회가 중지되고 더 이상의 범위는 검사되지 않습니다..

따라서 A이라는 이름은 기본 클래스 범위에서 처음 발견되며 전역 네임 스페이스의 이름은 여기에서 고려되지 않습니다. 그런 다음 액세스 권한 검사가 수행 된 후 컴파일이 실패합니다.

::A은 전체 범위에서 이름을 지정하고 문제를 해결하여 qualified name lookup이됩니다. 답변으로 내 의견을 게시

2

(주석보다 더 대답처럼 보인다) :

나는이 추측하고하는 것은 AC 내부 작업을위한 방법 이름 조회 때문이다. 먼저, 사용 전에 AC의 범위에있는 것으로 선언되었는지 확인합니다. 하나도 찾지 못했기 때문에 기본 클래스이므로 B의 범위에서 검사합니다. 그리고 인 경우에서 B 범위의 A를 찾지 못하면 global namespace을 보게됩니다. 그러나 어쨌든 A의 개인 상속이 B에 의해 두 번째 조회, 즉 B의 범위 내에서 중지되고 있습니다. fully qualified 이름을 사용하기 때문에 실제 문제가 같은 줄에 있어야한다고 생각합니다.