2014-03-27 3 views
3

같은 이름을 가진 중첩 클래스와 멤버 함수를 찾았습니다. 나는 주위에 방법을 찾고 있었다같은 이름을 가진 중첩 된 클래스와 멤버 함수

class Foo 
{ 
public: 
    class Lock 
    { 
     // Operations that require the lock... 
    }; 

    Lock Lock() noexcept {return Lock;} 
}; 

이 이해할 수 있도록 작동하지 않았고 시도 : 멤버 함수는 중첩 된 클래스의 인스턴스를 반환하기위한 것입니다

return typename Foo::Lock(); 

이것은 g에 괜찮 았는데 ++ 4.7 및 4.8하지만 3.4 ++ 그 소리에 실행할 때 내가 얻을 오류 : error: typename specifier refers to non-type member 'Lock' in 'Foo' C++ 11 : 'error: typename specifier refers to non-type member 'Lock' in 'Foo'

C++ (11)없이이것은 내 질문에 이릅니다 :

  • 이 중 어느 것이 맞습니까?
  • 예제와 같이 멤버 함수에서 중첩 클래스를 참조 할 수 있습니까?

답변

1

코드를 읽기가 힘들어 지므로 조언 해 드리겠습니다. 그러나 실제로 진행하려는 경우에는 중첩 클래스의 접두어를 class 키워드로 계속 사용해야합니다. 그 구문이 무효의 경우, 타입 정의 사용 오류에 관해서는

class Foo 
{ 
public: 
    class Lock 
    { 
     // Operations that require the lock... 
    }; 

    class Lock Lock() noexcept { 
     typedef class Lock cLock; 
     return cLock(); 
    } 
}; 

Live example

을, 그 소리는이 일에 대한 올바른 것입니다. 이 같은 명확성을 위해 typename을 사용할 수 없으며 템플릿 외부에서 사용할 수 있다고 생각하지 않습니다.

표준 참조 : Lockclass Lock을 숨기고이 class Lock로 액세스 할 수있는 방법을 방법

  • C++11[class.name]§4을 지정합니다.

  • C++11[class.name]§2는 명시한다 : 클래스 이름이 범위에서 선언

    경우 여기서 변수, 함수, 동일한 이름의 열거는 선언하거나, 다음 두 선언 범위에있는 클래스 단지 를 사용하여 참조 될 수 정교 형 지정자

    정교 형 지정자class X 형태이다. 이는 typename Foo::Lock이이를 참조하는 유효한 방법이 아니라는 것을 의미합니다.

+1

해결 방법을 이용해 주셔서 감사합니다. 정확성에 관해서는 위의 표준에 해당하는 부분을 가리킬 수 있다면 : – DrYap

+0

실제로 올바른 부분은 C++ 11 드래프트 표준 초안에서 '9.1'입니다. –

+0

정교한 형식 지정자를 사용하는 것뿐만 아니라'::'을 사용하여 클래스 이름에 액세스 할 수 있습니다 (표준에는 "두 선언이 모두 범위에있을 때"라는 의미로 사용됨). "이름이 정규화되지 않은 조회 ").이것은 유효합니다 :'foo :: Lock :: bar();','bar'는 Lock 중첩 클래스의 멤버 함수입니다. –

관련 문제