gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Template class member prototype help

#135260 - LOst? - Sat Jul 21, 2007 3:38 pm

Hello, some trouble in template land.

I need to make a prototype of "int TestB::j" and void "TestB::g (void)" for use with TestA. Help! And I can't reverse TestA's and TestB's order. Note that both TestA and TestB are derived from TestBase, and are templates!


Code:

// So far I know how to make a prototype of the class... But
// I need prototypes for some members too. What to do?
template <typename T, typename I>
class TestB;

template <typename T, typename I>
class TestA
:    public TestBase <T, I>
{
public:
    int i;

    void f (TestBase* pTest)
    {
        ((TestB <T, I>*) pTest)->g ();    // g function member is not defined in class TestB
        ((TestB <T, I>*) pTest)->j = 2;    // j member is not defined in class TestB
    }
};

template <typename T, typename I>
class TestB
:    public TestBase <T, I>
{
public:
    int j;

    void g (void)
    {
    }
};

_________________
Exceptions are fun

#135314 - sajiimori - Sun Jul 22, 2007 3:58 am

Reversing the order of the definitions is the obvious and simple solution, and if you think you can't do it, I'd consider rethinking your design.

But if you really want to leave the definitions backwards, you can define the body of TestA::f after TestB is defined, or have TestA::f do its work indirectly via some other function that's defined after TestB.

#135325 - sgeos - Sun Jul 22, 2007 9:22 am

sajiimori wrote:
and if you think you can't do it, I'd consider rethinking your design.

I suspect the old A needs B and B needs A applies to templates.
Code:
template <class Type> class B;

template <class Type>
class A
{
   B<Type> *list;
   // other members
};

template <class Type>
class B
{
   A<Type> data;
   // other members
};

Upon thinking about it, I don't know what you would be doing though... Generalized lists? I'm interested if anybody knows.

-Brendan

#135326 - keldon - Sun Jul 22, 2007 9:38 am

Well I tried this and it compiled perfectly fine (in Visual C++). Also if TestA depends on TestB then why must TestA be defined first? And what happens when pTest is not a TestB?

#135327 - wintermute - Sun Jul 22, 2007 10:37 am

Why don't we all pitch in and do people's homework for them? :P

Or is it just me that thinks this looks like a test question?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#135334 - keldon - Sun Jul 22, 2007 1:23 pm

wintermute wrote:
Why don't we all pitch in and do people's homework for them? :P

Or is it just me that thinks this looks like a test question?

lol; puns are Evil ^_^

#135343 - LOst? - Sun Jul 22, 2007 3:44 pm

Well, redesigning is in order. The example is just an example, because I wanted to know the forward declaration syntax.
_________________
Exceptions are fun

#135344 - keldon - Sun Jul 22, 2007 3:50 pm

Are you sure there's not something else wrong in your code, such as a class without a semi-colon? The reason I ask is because the code worked fine for me!!!

#135368 - sajiimori - Sun Jul 22, 2007 8:35 pm

The code highights a subtlety about how and when symbols are looked up for templatized code. I wouldn't be surprised if the behavior was different across compilers -- it's just one of those dark corners that should be avoided.

For more history on name lookups in templatized code, check out "The Design and Evolution of C++".

Oh, and don't blame templates for the problem (in case you were going to): if the code wasn't templatized, it would fail to compile on all compilers, rather than working on some of them.