Sign in to follow this  
janta

Forward declaration of a template class (c++)

Recommended Posts

janta    345
Hi, I've been reading a couple of tutorials and docs about templates for about one hour but still I could find the answer I'm looking for, so I hope someone could help here. I have defined a class like:
template <class T> BasicStack
And then in the same header I introduced a couple of helper typedefs like:
typedef BasicStack<int> IntBasicStack;
Now in another class header where i want to use that stuff, I got sth like:
class Logger
{
    BasicIntStack* m_pStateStack;
}
And of course, when I include logger.h, say in main.cpp (for example), BasicIntStack turns into an unknown type specifier. I sure know how to handle this when it deals with a regular class ( I just add some forward declaration in my header file) but now that is a template class and I'm unable to figure out what syntax I should be using.
class BasicIntStack; // error C2371: 'UTBoolStaticStack' : redefinition; different basic types
template <class T> class BasicIntStack; // error C2920: redefinition
template <class T> class BasicStack; // syntax error at the declaration of m_pStateStack
I know that with a child and a parent classes, the compiler always require both definitions to be able to compile, not just a simple forward declaration. So maybe templates works the same way and I should just include BasicStack.h into logger.h But that seems too dirty to me. Whatever, some help would be appreciated :) Janta =========== After more research, I succeeded to get someting clean by not using any typdef, just:
// forward decl
template <class T> class BasicStack;

class Logger
{
    BasicStack<int>* m_pStack;
}
But that does not fully satisfy me since full template names are really a p*** in the a** to use. Maybe add a typedef directly into the file of interest:
// forward decl
template <class T> class BasicStack;
typedef BasicStack<int> IntStack;

class Logger
{
    IntStack* m_pStack;
}
I guess I'll wait to see if someone can ofer me a different way of adressing this. Thanks :)

Share this post


Link to post
Share on other sites
ajones    432
Hi Janta,

you're right - for a template class declared like this:


template <typename T> class BasicStack
{
// stuff...
};


its forward declaration/predeclaration looks like this:


template <typename T> class BasicStack;


If you don't like typing a full declaration inside your Logger class, then I'd suggest using a Logger-scoped typedef like this:


class Logger
{
typedef BasicStack<int> statestack_type;
statestack_type* m_pStateStack;

// stuff...
};


Using this scheme, you limit the scope of the typedef so that it doesn't affect other classes, your typedef can have a more meaningful name because it is only used within the context of your logger, and you can continue to use stuff like statestack_type::iterator in your method definitions.

Hope this helps.
Cheers,
Jones.

Share this post


Link to post
Share on other sites
janta    345
Thanks for you reply ajones, that could be a solution.

But what I would have liked was to create one single alias for my BasicStack<int> which I could reuse everywhere in my code without re-typedef'ing every time.

So another solution I've vame up with is, instead of a typedef, declaring a new empty class like

class IntStack : public StaticStack<int>{};


I think this would work fine provided there are no private fields in the
StaticStack class.

And then I could forward-declare my class just like any other forward class declaration. Plys I could reuse it all over my code, since I plan to make my Stack class a part of my project's precompiled header.

I'll try this when back home tonight.

What do you say ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this