2010-11-19 3 views
3

을 사용하고 내가 뭔가를 알아낼 수 없을 때 나는 키워드 "유형 이름"을 사용해야 할 때 ..나는 작은 프로젝트에 최근에 일한지 템플릿

나는 .H 파일을 주어 졌어 그 typename 템플릿을 사용하여 클래스를 포함하고있었습니다. 그 수업 안에는 개인 수업이있었습니다. 나는 그래서

template<typename T> 
Node* Something::Function1(int index) //Is the return type well written? 
{ 
     // returns the node at the specified index 
} 

template<typename T> 
int Something::Index(const T& id) //Is the parameter type well specified? 
{ 
     // returns the index of the node with the specified id 
} 

도청 (A .inl 파일) 클래스 "뭔가"

여기

내가 그 일을했다 방법의 함수를 정의하고 싶어 할 때

template <typename T> 
class Something 
{ 
public: 
     Something(); 
     ~Something(); 

     Node* Function1(int index); 
     int Index(const T& id); 


private: 
     class Node() 
     { 
       public: 
       T id; 

       //Imagine the rest for the Node 


     };  
}; 

는 문제가 발생했습니다 part가 definition 부분에 있습니다 ... 반환 유형 (이 경우 Node *)이 typename 템플릿 (예 : typename Node*)을 사용한다는 것을 컴파일러에 알려야합니까? 그리고 매개 변수는 어떻습니까? typename const Node&?

그래서 기본적으로 함수/매개 변수가 템플릿을 사용하는 경우를 지정해야합니까?

감사합니다.

+0

귀하의 질문에 sinppets 게시물하십시오! – mmmmmmmm

+0

스 니펫과 링크를 게시했습니다. 내 스 니펫을 정확하게 들여 쓰는 방법을 알아낼 수 없었습니다. – Pacane

답변

2
template<typename T> 
typename Something<T>::Node * Something::Function1(int index) //Is the return type well written? 
{ 
     // returns the node at the specified index 
} 
+0

다른 방법의 매개 변수 유형은 어떻습니까? – Pacane

+3

'Node'는 중첩 된 클래스 이름입니다. 그래서 당신이'Something '메소드를위한 코드에 있거나'typename Something :: Node'라는 완전한 이름을 사용하지 않는다면 그것을 사용할 수 없습니다. 그리고 클래스 외부에 정의 된 메소드 리턴 타입은 아직 Something 메소드에 "들어 있지"않기 때문에 컴파일러에게 명확하게 알려줘야한다. 컴파일러는 항상'int'가 무엇을 의미하는지 알기 때문에 다른 방법은 그런 문제를 가지지 않을 것입니다. – aschepler

+0

설명과 시간을내어 주셔서 감사합니다. – Pacane

3

간단한 규칙을 다음 Class 부분은 템플릿 매개 변수에 따라 달라집니다 경우, 당신은 Class::Type 구문을 사용하여 유형을 이름 typename 키워드마다 시간을 사용해야합니다. 합니다 (Class 부분은 템플릿 매개 변수가 될 수도 있고, 당신의 클래스 템플릿에 typedef 등 수 있습니다)

편집 : 중첩 클래스의 범위 지정 규칙에 대한 혼란도있다. 이는 주로 typename 문제와 별개이므로 여기에는 템플릿이 아닌 예가 나와 있습니다.

class Outer { 
public: 
    class Inner { 
    }; 
    Inner* func(Inner* obj); 
}; 

Outer::Inner* func(Inner* obj) 
{ 
} 

Inner의 전체 이름은 Outer::Inner입니다. 그러나 더 짧은 이름 InnerOuter 클래스의 범위에서 사용할 수 있으며 모든 선언은 func입니다. func의 정의에서 반환 유형은 Outer의 범위가 아니므로 전체 이름이 필요합니다. 그러나 ( 이후에는 함수 매개 변수가 Outer의 범위에 있으므로 짧은 이름이 괜찮습니다. Outer의 상응 Something<T> 때문에 Something<T>::Node 말을 원래의 예의 템플릿 다움과이 결합

는, 당신은 typename 키워드가 필요합니다.

+0

그래서 함수 인덱스의 정의에있는 매개 변수 유형은 typename const 클래스 :: Node & id? – Pacane

+1

@Pacane : 의존적입니다.'T' 또는'Node'를 전달 하시겠습니까? 'Node'를 넘기고 싶다면 정식 버전이 작동 할 것이지만 컴파일러가'Something' 메서드를 정의하고'const Node &'를 정의하는 것을 보았으므로 필요하지 않습니다. – aschepler

+0

설명과 시간을내어 주셔서 감사합니다. – Pacane

5

Function1의 경우 컴파일러에게 어떤 노드가 있는지 알려줘야합니다.이 경우에는 Something<T> 안에 중첩 된 유형입니다. T (종속 이름)에 종속되어 있기 때문에 컴파일러에 유형이 있어야하므로 typename Something<T>::Node으로 작성해야합니다. 문제는 Something<T>::Node이 실제로 유형이 아닌 경우 (즉, 부분적으로 Something<T>을 전문으로하는 경우) 일 수 있습니다.

Index의 경우, const T&const T에 대한 참조 일 뿐이며 컴파일러는 T을 알고 있습니다.

+0

매개 변수가 노드에 대한 포인터 인 경우, 다시 typename 부분을 지정해야합니다. – Pacane

+1

'Something '안에 있기 때문에'Node *'라고 쓸 수 있습니다. 하지만 명시 적으로 작성했다면'Something :: Node *'가 아니라'typename Something :: Node *'라고 말할 필요가 있습니다. –

+0

설명과 시간을내어 주셔서 감사합니다. – Pacane

1

typenameclass 템플릿 유형 파라미터리스트 동일 : dependent names 참조 할 때

template <class T> class C; 

typename가 요구되는 경우

template <typename T> class C; 

와 동일하다 :

template <typename T> struct A { 
    typedef typename T::some_type container; 
}; 
+2

사실, typename과 class는 매개 변수 목록에서 동일하지 않습니다. typename 키워드는 템플릿 템플릿 매개 변수를 예상 할 때 'class'를 대체 할 수 없습니다. –

+0

예, 고맙습니다. 그것은 언어 부분에있는 부 - 부이지만 - 그들은 단지 내가 여기와 같은 경우에 대해 잊어 버렸습니다. :) –

관련 문제