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

How to forward declare a template class and use it as a member data in C++?

本文关键字:数据 成员 C++ 转发 声明      更新时间:2023-10-16

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

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上模板类的帖子,但没有一个回答我的问题。)

提前感谢!

这:

class A{
   B<T> b;
};

应该是这样的:

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

通过将B<T>添加到A中,基本上将A变成了模板类型为T的模板类,因此A类删除也应该被临时化。

首先,class A不是一个模板。因此,您必须使用类型(即,不是T)专门化B对象。其次,在成员变量的声明点(即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;
};

编辑:

如果你不知道在类A中声明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;
};

编辑:

请看我对101010的评论和大卫的回答。基本上,我想知道是否有可能在C++中实现以下目标:前向声明模板类B,然后将其用作类a的成员数据B的类型,而无需(1)将a作为模板类,(2)关心在声明B时将使用什么特殊类型。

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

远期申报

示例:

class Foo;

对于编译器来说,上面的语句意味着:"将在其他地方定义一个名为Foo的类"。从这一点开始,直到它的定义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;
};

模板类就像一个蓝图,可以用来创建许多类。要从模板创建类,您必须用具体值替换的参数。CCD_ 18和CCD_。

你可以做两件事:

待继续

进一步阅读:

定义和声明之间的区别是什么:https://stackoverflow.com/a/1410632/5420829
如何处理不完整类型:
https://stackoverflow.com/a/553869/5420829