2015-01-03 3 views
4

템플릿 템플릿 OuterTempl<T>inner 멤버를 만드는 것이 왜 타당한 지 설명하는 방법에 대해 손실이 있습니다. 템플릿이 작성되지 않은 클래스에서는 그렇지 않습니다. Outer .클래스 템플릿의 중첩 클래스가 "불완전"일 수 있습니다

// Non-template version 
struct Outer 
{ 
    struct Inner; 
    Inner inner; // incomplete type (I get this) 
}; 

struct Outer::Inner 
{ 
}; 

// Template version 
template<typename T> 
struct OuterTempl 
{ 
    struct InnerTempl; 
    InnerTempl inner; // OK ... Huh!? 
}; 

template<typename T> 
struct OuterTempl<T>::InnerTempl 
{ 
}; 

int main() 
{ 
} 

도 참조하십시오. ideone.

답변

4

예 - [temp.mem.class]/1 고려해

클래스 템플릿의 멤버 클래스가 선언 된 클래스 템플릿 정의 외부에 정의 할 수있다.
[참고 : 클래스는 처음 사용하기 전에 인스턴스화 (14.7.1)가 필요한 클래스를 정의해야합니다. 예를 들어,

template<class T> struct A { 
    class B; 
}; 

A<int>::B* b1; // OK: requires A to be defined but not A::B 

template<class T> class A<T>::B { }; 

A<int>::B b2; // OK: requires A::B to be defined 

- 엔드 노트]

은 위의 참고 설명 Inner의 사용을 구성 inner의 정의, 한 번만 인스턴스화 언급하는 것도 중요하다 필수 항목입니다 :

[...] 멤버가 명시 적으로 인스턴스화되거나 명시 적으로 특수화되지 않은 한, specializa 멤버 정의가 존재해야하는 문맥에서 전문화가 인 경우 멤버의 이 암시 적으로 인스턴스화됩니다.

OuterTempl의 어떤 인스턴스가 코드에 존재하지 않기 때문에

inner의 정의는 인스턴스화되지 않습니다, 그리고 Inner의 인스턴스는 필요로하지 않습니다. 따라서 이러한 선언에 대한 중첩 된 클래스 유형의 완성도는 인스턴스화 시점에서만 필요합니다. 여기서 OuterTempl을 인스턴스화하지 않지만 Inner의 정의 앞에 을 지정하면 코드가 잘못 구성됩니다. 이다

,

template<typename T> 
struct OuterTempl 
{ 
    struct InnerTempl; 
    InnerTempl inner; 
}; 

template struct OuterTempl<int>; // Bad - Ill-formed (NDR?) 

template<typename T> 
struct OuterTempl<T>::InnerTempl {}; 

template struct OuterTempl<int>; // Fine 

Demo.

4

클래스가 정의 될 때 멤버 유형을 정의해야합니다. 그러나 클래스 템플릿은 인스턴스화 될 때까지 정의되지 않습니다. 어떤 종류의 의존성 유형이 그때까지 바뀔 수 있습니다. 멤버의 정의는 클래스가 인스턴스화 될 때만 필요합니다.

한편, 비 템플릿 클래스의 정의는 그 시점에서 멤버의 크기를 알아야하는 정의입니다.

관련 문제