2010-02-22 6 views
1
template <class T> 
class List 
{ 
    public: 

     List(); 
     ~List(); 

     ... 

    protected: 

     template <class T> struct Item 
     { 
      struct Item* next; 
      T data; 
     }; 

     ... 

     struct Item<T>* allocate(); 
}; 

template <class T> 
struct Item<T>* List<T>::allocate() // error here 
{ 
    ... 
    return object; // struct Item<T>* 
} 

내가 어떻게 할 수 있습니까?C++ 템플릿 클래스 T 문제

+0

어떤 오류가 발생합니까? – FrustratedWithFormsDesigner

+0

내부 'Item'을 자체적으로 템플릿으로 만들 것인지 여부를 결정 했습니까? – AnT

+0

구문 오류입니다. 이제 작동합니다. thx to Matthieu M. – ohohoho

답변

1

문제는 사실에 깊은 : 그것은 T에 액세스 할 수있는 템플릿 클래스에서 중첩 클래스이기 때문에, 당신은 template 인 것으로 Item를 선언 할 필요는 없습니다

.

template <class T> 
class List 
{ 
public: 

private: 
    struct Item { ... }; 
}; 

그리고 당신은과 같이 access을 정의하는 것입니다 : 여기

template <class T> 
typename List<T>::Item List<T>::access(...) {} 

점은 매개 변수를 지정해야합니다 있도록 List 템플릿 클래스는 점이다, 한 번 TList에 지정된 상태가 아니다 그것을 다시 한번 정확하게하는 데 필요합니다.

참고 typename;)

+0

많이 있습니다. 이제 작동합니다. – ohohoho

2

는 쓰기 :

template <class T> 
struct List<T>::Item* List<T>::allocate() 
// etc 

:: 연산자는 항목 목록의 중첩 된 클래스입니다 컴파일러를 알려줍니다.

+0

아직 정확하지 않습니다 :) List :: Item *'이어야합니다. 또한,'struct'가 불필요하게하지 않는 한, 여분의'typename' 키워드가 필요할 수도 있습니다. 추신 아니,'구조체 '와 함께 필요하지 않습니다. – AnT

3

T 유형 이름을 다시 사용 중입니다. 사용 하나 다른 : template <class U> struct Item { ... (또는 모두 함께 Item에서 templatization를 제거 - 당신이 외부 템플릿 매개 변수를 잘처럼 보이는) :

template <class T> 
class List 
{ 
    ... 
    protected: 

     struct Item 
     { 
      Item* next; 
      T data; 
     }; 

     Item* allocate() { return object; } 
}; 
+1

왜 이것을 downvoted입니까? 클래스 템플릿이 인스턴스화 된 것과 동일한 유형을 다시 사용한다는 것이기 때문에 Item이 템플릿으로 선언 될 필요가 없습니다. –

+0

@Nick Meyer : (나는 그것을 downvote하지 않았다.) 그러나, 첫째, 그것은 클래스 정의에 관한 질문에 대답하지 않는다. 그리고 둘째, 의도를 어떻게 알 수 있습니까? OP에서 'Item'은 독립적 인 중첩 템플릿이며 다른 컨텍스트에서는 다른 용도로 사용할 수 있습니다. 그것은 외계인 계급과 같은 논점을 가지고 계시 될 것이라는 말은 없습니다. – AnT

+0

그리고 중첩 템플릿에 동일한 유형 이름을 사용하면 어떻게 도움이됩니까? –

3

방법 정의에 대한 올바른 구문은

template <class T> 
typename List<T>::Item* List<T>::allocate() 
{ 
    ... 
    return object; // struct Item<T>* 
} 
입니다 어떤 이유로 다른 포스터

는 (분명히, 원래 버전의 속임수) Item 대신 List<T> 부분을 부착 주장했다.

미안 해요, 난 Item은 그 자체로 tempate는 것을 발견하지 않았습니다. 이 경우는 그러나

template <class T> 
typename List<T>::template Item<T>* List<T>::allocate() 
{ 
    ... 
    return object; // struct Item<T>* 
} 

수있다, 내부 템플릿 선언에서 동일한 매개 변수 이름을 다시 사용하는 것은 불법이므로주의! 원래의 클래스 정의는 불법입니다.

template <class T> 
class List 
{ 
    ... 
    template <class U> struct Item // Note: `U` used intead of `T` 
    { 
    struct Item* next; 
    U data; 
    }; 
    ... 
    struct Item<T>* allocate(); 
}; 
+0

당신이 맞습니다! 이제 바뀌 었습니다. –

+0

List와 Item이 둘 다 템플릿이기 때문에'List :: Item *'일 필요는 없습니까? – sepp2k

+0

@ sepp2k : 네 말이 맞아. 나는 마침내 모든 조각과 조각을 마침내 얻었다라고 생각한다. – AnT

1

List::Item<T>의 형식을 지정해야합니다.

클래스 선언 내에 있거나 형식 목록 (또는 파생 클래스)의 각 멤버 함수의 인수 목록 또는 본문 내에있을 때 형식의 정규화되지 않은 이름을 사용할 수 있지만 반환 할 수는 없습니다 유형. 컴파일러가 반환 형식을 결정할 때 아직 템플릿의 List 멤버를 정의한다는 것을 알지 못하므로 해당 클래스 범위를 조사하지 않습니다.

template<typename T, typename U> 
auto sum(T lhs, U rhs) -> delctype(lhs+rhs) 
{ return lhs+rhs; } 

컴파일러 유형 T과 한 번 U을 추론 할 수있다 :

이 어떻게 컴파일러 실제로 반환 유형 정의처럼 auto 수 있도록 곧 표준의 일부 변경 영향을 미쳤다 작품의 흥미로운 점은 인수가 존재하지만 lhsrhs도 아직 범위에 있지 않으므로 반환 유형이 반환 유형으로 decltype(lhs+rhs)임을 알 수 없습니다. 이것은 C++의 유일한 문제이지만 직면 한 동일한 문제에 뿌리를두고 있습니다. 반환 유형의 범위는 선언되는 메서드의 범위 외부입니다.