2011-12-12 5 views
4

클래스의 멤버 유형을 나타 내기 위해 다른 곳에서 사용할 수있는 템플릿 클래스에 유형 이름을 정의하고 싶습니다.템플릿 내 typedef와 typename 사용하기

template <class T> 
class CA 
{ 
public: 
    //typedef typename T::iterator iterator_type; 
    typedef typename T ElementType1; // compile error on this line 
    //typedef T ElementType2; 

    T m_element; 
}; 

과 같이 사용 : 같은

template <class T> 
class CDerived : public CBase<typename T::ElementType1> 
{ 
//... 
}; 

및 선언 제품 :

typedef CDerived<CA> MyNewClass; 

가능이 아닌가?

typedef typename T ElementType1; 

은 분명히 컴파일러는 유형 이름 후 자격을 갖춘 이름을 기대하지만 난 템플릿 유형의 하나가 될 수있는 방법이 표시되지 않습니다 : 내가하지 라인을 사용 엑스 코드에서 제대로 VS2010에서하지만 컴파일 일부 코드가 .

이 컨텍스트에서 ElementType1과 ElementType2의 차이점을 이해하지 못합니다.

스택 오버플로에 대한 많은 질문을 보았지만 필자의 예제에서는 iterator_type과 같은 종류의 선언 만 언급 한 것 같습니다.

답변

4

컴파일러는 이미 T이 유형 (class T)임을 알고 있으므로 첫 번째 경우에 typename 한정자가 필요하지 않습니다. OTOH, 컴파일러는 사전에 T::ElementType1이 유형인지 알지 못합니다. 그것은 T가 끝나는 것에 달려 있습니다.

+0

제 질문에 대한 답변이 좋았으므로 'typedef T ElementType'을 사용해야합니다. 정말로 typename이 있어야하는지 잘 모르겠다. 나는 CBase '에서 그것의 사용법을 이해한다. 여기에 유형 이름 [link] (http://pages.cs.wisc.edu/~driscoll/typename.html)에 대한 자세한 정보가 있습니다. VS2010하지만 ElementType1 선언을 받아들이 듯하지만 gcc가 아닌 것 같습니다. – Robotbugs

4

typename은 정규화 된 이름을 한정하는 데에만 사용할 수 있습니다. 그것은 바로 다음에 오는 이름을 적용하지만,에, 즉, 정규화 된 이름에하지 않습니다

typedef typename T::X x; 

typename하면 TX에 적용하지. 따라서 은 정규화 된 이름 앞에 합법적으로 (이 용도로만) 사용할 수 있습니다. 정규화되지 않은 이름 은 컴파일러가 이름이 유형인지 여부를 알 수있는 컨텍스트에 있어야합니다. (실제로 이것은 종속 기본 클래스에 정의 된 유형의 문제 일뿐입니다.이 내용은 한정적 일 수 있습니다.)

관련 문제