如何转发声明模板类并将其用作C ++中的成员数据?

时间:2015-11-11 16:54:29

标签: c++

我正在尝试转发声明模板类,然后使用该类在其他类中声明成员数据。代码如下:

using namespace std;

template<class T>
class B;

class A{
   B<T> b;
};

template<class T>
class B{
    T x;
};

int main(){
}

我收到了编译错误:

error: ‘T’ was not declared in this scope
     B<T> b;

有谁能告诉我我做错了什么以及如何实现我的目标? (我注意到SO上模板类的帖子,但没有一个回答我的问题。)

提前多多感谢!

3 个答案:

答案 0 :(得分:4)

此:

class A{
   B<T> b;
};

应该是这样的:

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

通过将B<T>添加到A,您基本上将A转换为模板类,模板类型为T,因此A类删除应该也是寺庙化的。

答案 1 :(得分:2)

首先,class A不是模板。因此,您必须使用类型(即,不是B)专门化您的T对象。其次,在您的成员变量声明(即b)时,B是一个不完整的类型。因此,您只能有一个指针或对它的引用。

template<class T>
class B;

class A{
   B<int> *b;
     ^^^  ^
};

template<class T>
class B{
    T x;
};

或者如果这不会产生任何影响。如果您希望具体的B对象更改类AB的定义顺序,因为在您的示例中BA无关:

template<class T>
class B{
    T x;
};

class A{
   B<int> b;
};

编辑:

如果您不知道在B类声明b时您将使用哪种特殊类型(因此添加“”是不可行的)那么您必须使class A成为模板同样。这样做可以使具体类型为B

template<class T>
class B;

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

template<class T>
class B{
    T x;
};

答案 2 :(得分:1)

编辑:

  

请参阅我对101010的评论以及David的回答。基本上,我想知道是否有可能在C ++中实现以下目标:转发声明模板类B,然后将其用作类A的成员数据b的类型,而不是(1)使A成为模板类, (2)关注在宣布b时将使用的特殊类型。

你所要求的是没有意义的。这不是你的错。你只是误解了C ++的工作原理。让我向你解释一下。

转发声明

示例:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" id="btn">Click</button>

<div class="stillObj"></div>

<div id="outer">
   <div class="inner">
      <div>
         <div class="item"></div>   
      </div>
        <div class="itemBelow">
            <div class="innerBelow"></div>
        </div> 
   </div>
</div>

对于编译器,上面的语句意味着:&#34;在其他地方会有一个名为Foo的类&#34;。从这一点开始直到它的定义 Foo是不完整类型。有些事情你可以用不完整的类型做,有些事情是你不能做的。特别是:您不能声明该类型的变量和成员变量(也称为字段)。例如:

class Foo;

使用不完整类型可以执行的操作之一是声明指向它的指针。例如:

class Foo;

class Bar0
{
    Foo f;  // syntax error: Foo is an incomplete type
};

void fun0(Foo f)  // syntax error: Foo is an incomplete type
{
    Foo f;  // syntax error: Foo is an incomplete type
}

class Foo
{
    int x;
    Foo f;  // syntax error: Foo is an incomplete type
    void fun(Foo other) {  // Ok here: see "note"
    }
};  // Foo becomes complete here.
// Note: things are actually more complicated
// for example: Foo is complete inside it's own methods
// even if they are defined inside the definition of Foo.

class Bar1
{
    Foo f;  // Ok here: Foo is complete
};

void fun1(Foo f)  // Ok here: Foo is complete
{
    Foo f;  // Ok here: Foo is complete
}

模板

示例:

class Foo;

void fun(Foo* f)  // Ok here
{
}


class Bar
{
    Foo* f;  // Ok here
};

模板类就像一个蓝图,可用于创建许多类。要从模板创建类,您必须使用具体值替换它的参数。 template<class Bar> class Foo { Bar b; }; Foo<int>是两种不同的类型。

您可以做两件事:

继续

进一步阅读:

定义和声明之间有什么区别:Fiddle
你可以用不完整的类型做什么:
https://stackoverflow.com/a/1410632/5420829