简体   繁体   中英

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

I am trying to forward declare a template class then use the class to declare a member data in some other class. The code is below:

using namespace std;

template<class T>
class B;

class A{
   B<T> b;
};

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

int main(){
}

I got the compilation error:

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

Can anybody let me know what I did wrong and how to achieve my goal? (I noticed the posts on template class on SO, but none of them answers my question.)

Thanks a lot in advance!

This:

class A{
   B<T> b;
};

should be this :

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

By adding B<T> into A , you basically turned A into a template class as well with the template type T , so A class deleration should be templetized as well.

Firstly, class A is not a template. Thus, you must specialize your B object with a type (ie, not T ). Secondly, at the point of your member variable's declaration (ie, b ), B is an incomplete type. Thus, you can only have a pointer or a reference to it.

template<class T>
class B;

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

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

Alternatively and if this doesn't cause any implications. If you want a concrete B object change the order of definition of class A and B , since in your example B doesn't relate with A :

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

class A{
   B<int> b;
};

Edit:

If you don't know what special type you'll use for B (so adding "" is infeasible) at the time the declaration of b in class A. Then you have to make your class A a template as well. Doing so you can have a concrete type of B :

template<class T>
class B;

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

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

Edit:

Please see my comments to 101010 and David's answer. Basically, I am wondering if it is possible to achieve the following goal in C++: forward declare a template class B, then use it as the type of the member data b of a class A, without (1) making A a template class and (2) caring about what special type will be used upon the time of the declaration of b.

What you are asking for makes no sense. It's not your fault. You are just misunderstanding how C++ works. Let me explain it to you.

Forward declaration

Example:

class Foo;

To the compiler the above statement means: "There will be a class named Foo defined somewhere else". From this point and until the it's definition Foo is an incomplete type . There are things you can do with an incomplete type and there are things you can't. In particular: you can't declare variables, and member variables (aka fields) of that type. Example:

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
}

One of the things you can do with an incomplete type is declare a pointer to it. For example:

class Foo;

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


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

Templates

Example:

template<class Bar>
class Foo
{
    Bar b;
};

Template class is like a blueprint that can be used to create many classes. To create a class from a template you have to substitute it's arguments with concrete values. Foo<int> and Foo<long> are two separate types.

There are two things you can do:

To be continued

Further reading:

What is the difference between a definition and a declaration: https://stackoverflow.com/a/1410632/5420829
What can you do with an incomplete type:
https://stackoverflow.com/a/553869/5420829

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM