template and include files

Y

Yamin

Hi all,

I was porting some code over to GCC, when I came across some code. GCC gave
a compile error. I looked it over and to me at least it looked like it
should have never compiled. But this code was supposedly compiled on WATCOM
and green hills.

I am assuming GCC is correct in denying the code, but does anyone know how
another compiler would even accept it. Or has anyone come across this
'pattern' before.

Here's a rough outline of the code. Please ignore the syntax. This is just
a rough outline, and its not my code.

BEGIN CODE
***************************************
**************************
pool.h
**************************
template<class T>
class pool
{
....
T *getObject();
void foo(T *x);
};

template<class T>
class T *pool<T>::getObject()
{
....some code
}

template<class T>
void pool<T>::foo(T *x)
{
x->implied(); //implied assumed to be part of class T
}
**************************
control.h
**************************
class A; //forward declare

class B
{
...
pool<A> mypool;
}

class A
{
...
void implied();
B myB;
}

********************************

This to me is a circular reference. To construct B, the size of A needs to
be known (pool<A>). To contruct A, the size of B needs to be known. Even
if A is put in front of B, the same is still true. To be honest, I can't
remeber which came first from the code :).

I fixed it already by dynamically assigning the B within A...

Any ideas. Is there something special about templates that allows this to
occur?

Yamin
 
R

Rob Williscroft

Yamin wrote in
Hi all,

I was porting some code over to GCC, when I came across some code.
GCC gave a compile error. I looked it over and to me at least it
looked like it should have never compiled. But this code was
supposedly compiled on WATCOM and green hills.

I am assuming GCC is correct in denying the code, but does anyone know
how another compiler would even accept it. Or has anyone come across
this 'pattern' before.

To answer that we would need to see code that exibited the behaviour,
I haven't checked but with the gaps filled in I would expect gcc (I
have 3.2/Mingw) to compile your example below.
Here's a rough outline of the code. Please ignore the syntax. This
is just a rough outline, and its not my code.

BEGIN CODE
***************************************
**************************
pool.h
**************************
template<class T>
class pool
{
...
T *getObject();
void foo(T *x);
};

template<class T>
class T *pool<T>::getObject()
{
...some code
}

template<class T>
void pool<T>::foo(T *x)
{
x->implied(); //implied assumed to be part of class T
}
**************************
control.h
**************************
class A; //forward declare

class B
{
...
pool<A> mypool;
}

class A
{
...
void implied();
B myB;
}

********************************

This to me is a circular reference. To construct B, the size of A
needs to be known (pool<A>).

To contruct A, the size of B needs to
be known. Even if A is put in front of B, the same is still true. To
be honest, I can't remeber which came first from the code :).

I fixed it already by dynamically assigning the B within A...

Any ideas. Is there something special about templates that allows
this to occur?

Not really though the real problem you encouterd may have.

Change the above to:

class A;
class pool
{
A *getObject();
void foo(A *x);
};

class B
{
pool mypool;
};

class A
{
void implied();
B myB;
};

A *pool::getObject()
{
//...some code
}

void pool::foo(A *x)
{
x->implied(); //implied assumed to be part of class T
}

I hope you can see from the above that the class pool isn't dependant
on having a complete defenition of A. Only is member function's are.

Rob.
 
Y

Yamin

Rob Williscroft said:
Yamin wrote in

To answer that we would need to see code that exibited the behaviour,
I haven't checked but with the gaps filled in I would expect gcc (I
have 3.2/Mingw) to compile your example below.


Not really though the real problem you encouterd may have.

Change the above to:

class A;
class pool
{
A *getObject();
void foo(A *x);
};

class B
{
pool mypool;
};

class A
{
void implied();
B myB;
};

A *pool::getObject()
{
//...some code
}

void pool::foo(A *x)
{
x->implied(); //implied assumed to be part of class T
}

I hope you can see from the above that the class pool isn't dependant
on having a complete defenition of A. Only is member function's are.

Rob.

Ah, yes I see. Perhaps I should've looked for that situation of a sizeless
class. I've just become so used to seeing that pattern, that I
automatically assumed something was wrong with the code. Just to make sure
I'm not insane though:

If the class A had any member variables then there would be a
problem...correct? I'll make sure of that tomorrow at work.

Yamin
 
R

Rob Williscroft

Yamin wrote in
Ah, yes I see. Perhaps I should've looked for that situation of a
sizeless class. I've just become so used to seeing that pattern, that
I automatically assumed something was wrong with the code. Just to
make sure I'm not insane though:

If the class A had any member variables then there would be a
problem...correct? I'll make sure of that tomorrow at work.

Not really 'A' does have a member variable, a 'B', and it could have
more.

The reason it works is that 'class pool' only needed to now that 'A' is
a type-name, the "class A;" forward declaration in my example and
the "... <typename T> ..." (where T = A when pool<A> was instantiated)
in your example were sufficient to do this.

Rob.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top