2013-05-26 5 views
3

선언 된 클래스 외부의 내부 클래스를 정의하는 데 문제가 있습니다.두 레벨 중첩 된 C++ 클래스는 GCC와 함께 작동하지만 Clang과 함께 실패합니다.

struct Base { 
    struct A { 
     struct B; 
    }; 
    struct A::B { 
    }; 
}; 

그것은 컴파일하고 GCC와 함께 작동하지만이 오류와 함께 연타에 실패

innerclass.cpp:6:12: error: non-friend class member 'B' cannot have a qualified name 
    struct A::B { 
      ~~~^ 

가장 바깥 쪽 클래스베이스 코드가 연타 작동 생략됩니다.

이런 식으로 내부 클래스를 정의하는 것은 불법입니까? 그렇다면 어떻게해야합니까?

플랫폼 :
OS X 10.8.3
엑스 코드 4.6.2
연타 애플 LLVM 버전 4.2 (그 소리-425.0.24)
GCC의 GCC 버전 (LLVM의 3.2svn 기준) 4.2.1 (기반 Apple Inc. build 5658) (LLVM 빌드 2336.11.00)

답변

5

GCC가 허용하고 있습니다. 의 9/1 문단 C++ 11 표준은 클래스 헤드 이름이 있음을 지정합니다

중첩 된 이름 지정 (선택 하) 클래스 이름을 정규화 된 이름을 의미

클래스의 이름으로 사용할 수 있습니다.

If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, [...]

을 그리고 당신은 참으로 클래스 A 내부 클래스 B를 선언 않았다 또한, 단락 9.11의 첫 번째 부분을 지정합니다. 그러나, 같은 단락의 두 번째 부분은 추가 : 귀하의 경우

[...] and the class-specifiershall appear in a namespace enclosing the previous declaration. In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.

클래스 지정struct A::B { } 네임 스페이스의 범위에 표시하지만, 클래스의 범위 (변경하려고하지 않습니다 struct Basenamespace Base으로 변경하면 Clang이 승인하는 것을 볼 수 있습니다. Base

따라서, 이러한 고정 방법은 정확한 공간 범위에있는 클래스를 정의하는 것, 그리고 내부 :

// ... 

struct Base::A::B 
{ 
};