Some problems with forward declarations

M

mjm

Folks,

Please help me with the following problems:

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

1. I have a class template

template<class Base> class Matrix : public Base { /* .... */ }

then

typedef Matrix<UpperTriangular> UTRMatrix;

My question is now: how do I refer to the class UTRMatrix in a forward
declaration? The following does not work

class UTRMatrix;

("Conflicting types for struct UTRMatrix").

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

2. When I try a forward declaration

std::string;

I get the error message: "specialization of string after
instantiation".

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

3. I have a class MyClass with a static const int member J.
Now in a header file I have to refer to MyClass::J.
I don't want to include MyClass.h so I am trying the forward
declarations

class MyClass;
extern int MyClass::J;

The compiler does not like that:
"Struct MyClass not yet defined".
How should I do it?


Many thanks.
 
V

Victor Bazarov

mjm said:
Please help me with the following problems:

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

1. I have a class template

template<class Base> class Matrix : public Base { /* .... */ }

then

typedef Matrix<UpperTriangular> UTRMatrix;

My question is now: how do I refer to the class UTRMatrix in a forward
declaration? The following does not work

class UTRMatrix;

("Conflicting types for struct UTRMatrix").

You have already declared 'UTRMatrix'. Why do you need another
[forward] declaration?
********************************************

2. When I try a forward declaration

std::string;

That's not a forward declaration. Please restate your question.
I get the error message: "specialization of string after
instantiation".

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

3. I have a class MyClass with a static const int member J.
Now in a header file I have to refer to MyClass::J.
I don't want to include MyClass.h so I am trying the forward
declarations

class MyClass;
extern int MyClass::J;

No. Forward declaration of members is prohibited.
The compiler does not like that:
"Struct MyClass not yet defined".
How should I do it?

You shouldn't. What are you trying to accomplish? Perhaps your
static const would be better off outside the class?

Victor
 
D

Darryl Melander

1. I have a class template
template<class Base> class Matrix : public Base { /* .... */ }

then

typedef Matrix<UpperTriangular> UTRMatrix;

My question is now: how do I refer to the class UTRMatrix in a forward
declaration?

You forward declare Matrix and then do the typedef:

template<class Base> class Matrix;
class UpperTriangle;
typedef Matrix<UpperTriangular> UTRMatrix;

Since you can't legally typedef UTRMatrix twice in the same compilation
unit, you probably ought to put those lines in a header file somewhere. And
since that means you're already including a header, it probably makes sense
to go ahead and include the full header that you're trying to avoid with the
forward declaration...
std::string;

I get the error message: "specialization of string after
instantiation".

As stated by someone else, that isn't a forward declaration. A forward
declaration would be:

namespace std
{
class string;
}

With standard includes in particular, there is almost never a reason to
forward declare instead of just including the header. Go ahead and include
3. I have a class MyClass with a static const int member J.
Now in a header file I have to refer to MyClass::J.
I don't want to include MyClass.h so I am trying the forward
declarations

class MyClass;
extern int MyClass::J;

The compiler does not like that:
"Struct MyClass not yet defined".
How should I do it?

If you're going to access a member of a given class, even a static member,
you MUST include the class declaration. There's no getting around including
the header file on this one...

Perhaps you should ask yourself why you need to avoid including header
files. I realize that forward declarations are a wonderful way to help
reduce file dependencies; I use them all the time. But the need for too
many forward declarations can also be a sign that your project has too many
logical file interdependencies.

Thanks,

Darryl
 
M

mjm

Thanks for all the replies.
The reason I was asking is that I am trying to minimize includes in
header files.
If you include something in a header file it will be included wherever
that header file is included -- possibly needlessly.

That's why it's best to minimize the information in the header file
and instead include the stuff in the source files where it is really
needed.

For example: Matrix.h contains a class template that is fully defined
in the header and fairly large. I definitely don't want to include
Matrix.h in a header unless it is absolutely necessary. The typdef

typedef Matrix<UpperTriangular> UTRMatrix;

is in the header Matrix.h. In some other header I might need a
declaration of
UTRMatrix but not the definition. So I do not need to include Matrix.h
instead all I need is a forward declaration

class UTRMatrix;

But the compiler does not like that. For the same reason I do not
want to include <iostream> in a header if I don't have to. I always
get by with (GCC 2.95.3)

class std::eek:stream;

I was also thinking that it might have to be

namespace std {

class ostream;

}

but

class std::eek:stream works also. Why can't I do

class std::string;

The greatest nuisance is that I do not know how to forward declare
something that was defined by a typedef. I assume that this is a
common problem.
 

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

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top