2009-10-26 1 views
9

여기에는 보호 된 멤버 변수를 사용하는 오래된 코드베이스가 있습니다. 이것이 좋은 아이디어인지 여부는 논의 될 수 있습니다. 그러나 코드는 gcc3으로 컴파일해야합니다. 나는 그렇게파생 클래스에서 클래스의 보호 된 멤버에 액세스

template <class Something> class Foo { 
public: 
// stuff... 
protected: 
    some::type x; 
} 

template <class Something> Bar : Foo<Something> { 
public: 
    void cleanup(); 
} 

처럼 그리고 정리의 메소드 선언()이 수행

template <class Something> void Bar<Something>::cleanup() { 
    doSomeThingCleanUpLike (x); 
} 

X 함께 할 뭔가가에 클래스 템플릿 푸에서 멤버 X를 보호 사용하는 파생 된 템플릿 클래스 바있다 gcc4와 함께 작동하지 않아도 gcc4와 작동하지 않습니다. 변경하면 작동합니다.

doSomeThingCleanUpLike (this->x); 

왜 그런가요?

+1

"템플릿 클래스"라는 용어는 흔히 혼동의 원인입니다. 클래스의 템플릿이기 때문에 올바른 용어는 "클래스 템플릿"입니다. 그것은 수업이 아닙니다. 나는 당신의 질문을 편집 하겠지만 아마도 당신이 혼란스러워하는 이유 중 하나 일 것입니다. – MSalters

+1

함수 정의에서 "정리"가 적합하지 않습니다. "Bar"에 대한 리턴 유형 및 템플리트 인수가 누락되었습니다. 물론 그것은 당신의 코드에 어떻게 있습니까? –

+0

감사합니다. litb. 나는 그것을 바꿨다. 카페인 수준은 그것을 발견 할만큼 충분히 높지 않았습니다. "클래스 템플릿"으로 변경되었습니다. 템플릿 클래스 또는 클래스 템플릿이 문제에 영향을주지 않아야하는지 여부. 이 용어는 단지 비공식적으로 많이 사용됩니다. – GeeF

답변

13

파생 클래스에 사용 된 표현 x은 표준의 규칙에 따라 파생 클래스의 템플릿 매개 변수에 종속되지 않습니다. 이 때문에 조회는 템플릿 정의의 컨텍스트에서 발생하지만 사용/인스턴스화 시점에서는 발생하지 않습니다. 템플리트의 템플리트 기본 클래스가 표시되는 것처럼 보이지만, 템플리트 클래스이기 때문에 사용될 수있는 특정 인스턴스화에는 특수한 템플리트가 포함될 수 있으므로 기본 클래스 템플리트 정의를 이름 검색에 사용할 수 없습니다.

표현식을 this->x으로 변경하면 종속 표현식이됩니다 (클래스 템플릿의 this은 항상 템플릿 매개 변수에 따라 다릅니다). 즉, 기본 클래스가 완전히 알려지고 멤버가 표시되는 인스턴스화 컨텍스트에서 조회가 수행됩니다.

+0

+1 적절한 용어 사용 : * dependent */* non-dependent * names. –

6

파생 된 템플릿을 정의 할 때 컴파일러는 기본 템플릿 클래스의 이름 만 알고 있지만 세부 정보는 알 수 없으므로 파생 클래스에 상속 된 멤버가 없다는 것을 컴파일러에서 알 수 없습니다. 컴파일러에게 회원의 존재를 알리기 위해, 당신이했던 것처럼 this->을 사용하십시오.

실제로는 this question의 복제본입니다.

+1

'this->'를 추가하는 것은 의식이 아닌 비 종속 이름을 종속적 이름으로 변환하는 방법입니다. 찰스의 답변을 참조하십시오. –

+0

좋은 캐치, 그 질문 _had_ 나쁜 제목. 이제 해결되었습니다. – MSalters