类模板的嵌套类可以是“不完整的". [英] Nested class of class template can be "incomplete"

查看:66
本文介绍了类模板的嵌套类可以是“不完整的".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何解释为什么在类模板 OuterTempl< T> 中创建成员 inner 是有效的,但是在未模板化的类外部中执行此操作.

 //非模板版本结构外{内部构造内在的内在;//不完整的类型(我明白了)};结构外部::内部{};//模板版本template< typename T>struct OuterTempl{struct InnerTempl;InnerTempl内部;//好吧... Hu!};template< typename T>struct OuterTempl< T> :: InnerTempl{};int main(){} 

另请参见 ideone .

解决方案

是-考虑[temp.mem.class]/1:

可以在类之外定义类模板的成员类在其中声明它的模板定义.
[注意: 成员类必须在其首次使用之前定义,该类需要一个实例化(14.7.1).例如,

  template< class T>结构A {B级;};A< int ::: B * b1;//OK:需要定义A,但不需要A :: B模板< T类>类A&T; :: B {};A< int> :: B b2;//OK:需要定义A :: B 

—尾注]

还必须提及的是,构成上述注释所描述的 Inner inner 的定义仅在需要时才实例化:

除非成员[…]已显式实例化或显式专门化,否则专门化当专门化是在需要成员定义存在的上下文中引用;

由于您的代码中没有 OuterTempl 的实例化,所以 inner 的定义不会被实例化,并且 Inner 的实例化也不会被实例化必要的.因此,仅在实例化时才需要此类声明的嵌套类类型的完整性.您无需在此处实例化 OuterTempl ,但是如果在 Inner 的定义之前执行,则代码将格式错误./p>

也就是说,

  template< typename T>struct OuterTempl{struct InnerTempl;InnerTempl内部;};模板结构OuterTempl< int> ;;//错误-格式错误(NDR?)template< typename T>struct OuterTempl< T> :: InnerTempl {};模板结构OuterTempl< int> ;;//美好的 

演示 .

I'm at a loss as to how to explain why it is valid to create the member inner in the class template OuterTempl<T> whereas it is illegal to do so in the untemplated class 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()
{
}

See also ideone.

解决方案

Yes - consider [temp.mem.class]/1:

A member class of a class template may be defined outside the class template definition in which it is declared.
[ Note: The member class must be defined before its first use that requires an instantiation (14.7.1). For example,

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

— end note ]

It is also important to mention that the definition of inner, which constitutes the use of Inner the above note describes, is only instantiated once it is required:

Unless a member […] has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist;

Since no instantiation of OuterTempl is present in your code, the definition of inner is never instantiated, and an instantiation of Inner is never necessitated. The completeness of the nested class type for such a declaration is thus only required at the point of instantiation. You don't instantiate OuterTempl here, but if you would do that before the definition of Inner, the code would be ill-formed.

That is,

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.

这篇关于类模板的嵌套类可以是“不完整的".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆