From: richarm@a.cs.okstate.edu (MCINTYRE RICHARD D)
Subject: Friends, Template Classes, and Order of Declaration?
Organization: Oklahoma State University, Computer Science, Stillwater
Date: Thu, 28 Jan 93 16:10:16 GMT

Can anyone explain to me some anomolies I get when
I make changes to the code below?  This is a very simlified
example of a similar situation that I'm in.  If I swap the
order of lines 53 and 54, then line 36 gets flagged with an
error message stating:
  'd1<int>' must be previously defined class or struct.

Since d1<int> is an abstract base class, I can't have a real
instantiation of that type, even though the pointer to it
should be legal.

In my actual situation, I have several classes, and there
does not seem to be a suitable order of declaration that
will resolve the problem.  I have made sure that within the
class definitions I don't have any objects of a type that
has not been declared yet, and I have no pointers to such
objects either.

To confound the situation further, the friend declaration on
line 12 affects things somehow.  The friend declaration cannot
be removed without changing the 'private:' declaration on
line 20 to either 'protected:' or 'public:'.

In my actual situation, I reluctantly had to grant public
visability to what I would rather have as protected data and
functions in my base classes.  Then I had to remove the friend
declarations so that I could get the compiler to ignore the
order of declarations.  This in addition to some other
compromises I won't go into.

If it makes any difference, I'm using BC++ 3.1.  I'd be curious
to know if a similar message appears on any other compilers.
I don't have access to another compiler that supports templates,
or I'd test it myself.

//>--------------------- CUT HERE -----------------------<

#include <strstream.h>
/* 1: */
/* 2: */
/* 3: */ //*******************************************************
/* 4: */ class b2 {
/* 5: */	protected:
/* 6: */		virtual int getcount( void ) const = 0;
/* 7: */	};
/* 8: */
/* 9: */ //*******************************************************
/*10: */ template <class Type>
/*11: */ class b1 {
/*12: */ 	friend class d2<Type>;
/*13: */
/*14: */	public:	b1( void ) { count = 0; }
/*15: */	  virtual ~b1( void ) {}
/*16: */	  virtual void foo( void ) {}
/*17: */
/*18: */	protected: int count;
/*19: */
/*20: */   	private: int x;
/*21: */		 void inc_x( void ){ ++x; }
/*22: */	};
/*23: */
/*24: */ //*******************************************************
/*25: */ template <class Type>
/*26: */ class d1 : protected b1<Type> {
/*27: */	public:
/*28: */	  virtual ~d1( void ) {};
/*29: */	  virtual int getnum( void ) const = 0;
/*30: */
/*31: */	protected: int num;
/*32: */	};
/*33: */
/*34: */ //*******************************************************
/*35: */ template <class Type>
/*36: */ class d2 : private d1<Type>, private b2 {
/*37: */
/*38: */	public:
/*39: */	  d2( void ) {}
/*40: */	 ~d2( void ) {};
/*41: */
/*42: */	  int getnum( void ) const { return num; }
/*43: */
/*44: */	  // INHERITED VIRTUAL FUNCTION FROM CLASS b2
/*45: */	  int getcount( void )
/*46: */	    { inc_x();
/*47: */	      return count; }
/*48: */  	};
/*49: */
/*50: */ //*******************************************************
/*51: */ void main( void )
/*52: */  {
/*53: */  d2<int> *d2x; // If this line gets swapped with #54, then
/*54: */  d1<int> *d1x; // I get an error as described above.
/*55: */  b1<int> b1x;
/*56: */  }

//>------------------ CUT HERE ----------------------------<

As a side note, does anyone know why the C++ Report costs
$4.95 off the newsrack, but is $69 to subscribe?  A difference
of $24.45 to have it delivered to your mailbox!  Postage and
Handling?

Thanx in advance to anyone who can shed some light on either
one of these mysteries.  I read the postings here quite regularly
so followups will be fine.

Regards.

-- 
Name :		    Dallas McIntyre
Occupation :	    Student - Still looking for a "real" job.
Email Address :	    richarm@a.cs.okstate.edu
Favorite Far Side : Tarzan Introducing Himself to Jane.