Forward declaration of a template class (c++)

Started by
1 comment, last by janta 17 years, 11 months ago
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 :)
Advertisement
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.
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 ?

This topic is closed to new replies.

Advertisement