2011-03-13 5 views
16

다음과 같이 GetContainer() 함수가 있습니다.g ++ 템플릿 매개 변수 오류

template<typename I,typename T,typename Container> 
Container& ObjCollection<I,T,Container>::GetContainer() 
{ 
    return mContainer; 
} 

나는 오류를 가지고

template<typename I,typename T> 
T& DynamicObjCollection<I,T>::Insert(T& t) 
{ 
    GetContainer().insert(&t); 
    return t; 
} 

다음과 같이 나는이 방법을 사용합니다.

error: there are no arguments to ‘GetContainer’ that depend on a template parameter, 
so a declaration of ‘GetContainer’ must be available 

error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of 
an undeclared name is deprecated) 

MSVC에서 잘 작동하지만 g ++는 그렇게 관대하지 않습니다. 코드에 어떤 문제가 있습니까?

+0

문제를 나타내는 완전한 컴파일 가능한 예제를 게시 할 수 있습니까? –

답변

53

GetContainer 함수는 ObjCollection의 함수이고, InsertDynamicObjectCollection의 멤버 인 것으로 나타났습니다. 여기에서 DynamicObjectCollectionObjectCollection에서 상속 받았다고 가정합니다.

실제로 그렇다면 템플릿 기본 클래스에서 상속 한 템플릿 클래스를 작성할 때 이름 조회가 작동하는 방식이 일반 클래스에서 이름 조회와 약간 다릅니다. 특히 이름을 사용하여 기본 클래스 멤버를 참조 할 수는 없습니다. 컴파일러에게 어디에서 이름을 찾을 지 알려줄 필요가있다. Visual Studio에서 이것이 작동하는 이유는 Microsoft C++ 컴파일러가 실제로이 동작을 잘못 받아들이므로 기술적으로 올바르지 않은 코드를 컴파일하는 것이 허용됩니다.

기본 클래스의 GetContainer 함수를 호출하려면 두 가지 옵션이 있습니다. 첫째, 통화가 멤버 함수임을 나타냅니다 명시 적으로 할 수 있습니다

this->GetContainer().insert(&t); 

이제 컴파일러는 GetContainer은 그것이 기본 클래스에 GetContainer를 검색해야 할 수도 있음을 알고, DynamicObjectCollection의 구성원인지 알고, 템플리트가 인스턴스화 될 때까지 이름 조회를 연기합니다.

template <typename I, typename T> 
class DynamicObjectCollection: public ObjectCollection<I, T, /* ? */> { 
public: 
    using ObjectCollection<I, T, /* ? */>::GetContainer; 

    /* ... */ 
}; 

이것은 또한 GetContainer 기본 클래스에 정의 될 수 컴파일러에 명확하게 표시하고, 그래서 때까지 조회를 연기 : 사용할 수

다른 옵션은 클래스 본문에 using 선언을 추가하는 것입니다 템플릿 인스턴스화.

이 상황에 해당되지 않는 경우 알려 주시면이 게시물을 삭제할 수 있습니다.

희망이 도움이됩니다.

+5

+1 빠른 타이핑 – Erik

+1

고마워요! 이제 작동합니다. – prosseek