[comp.lang.c++] generic types

djones@megatest.UUCP (Dave Jones) (01/16/88)

Greetings++;

I've been thinking about how to automate the process of deriving type-
secure classes from generic base-classes.  I'm not completely happy with
the method of doing it that's described in The Book on page 209.

As a matter of convention, I would prefer a different style, as illustrated
by the following #define from the class-library I am currently 
building:

// A dervied class of Assoc, named _name_, which implements 
// associative arrays, mapping null-terminated strings to values of 
// type _value_.
#define NAME_TABLE(_name_,_value_) \
class _name_ : public Assoc \
{ \
  public: \
    _name_ () : (sizeof(_value_)) {} \
    _value_& operator[] (char* key) \
      { return *((_value_*)Assoc::lookup(key));} \
} // note: no semicolon

Building the _name_ automatically from the type-names, as on page 209
of The Book,  can result in multiple defines. Or, if the user forgets 
and uses "char*", say, instead of a typename, he will get a jillion nonsense 
error messages.

So, let the user choose the (obligatory) name.  Leave off the semicolon.

Then you can use it as a class-definition, or as you would a defined type:

    NAME_TABLE(String_table, char*);  // class definition
    String_table string_table;   // uses the derived class

    //  Used like an already defined type...
    NAME_TABLE(Name_table, struct name_entry) name_table;


By the way... point two:


I would prefer to be able to define a macro that expands to an anonymous
type, then use the macro like a type-descriptor:

NAME_TABLE(struct name_entry) lookup_table;

But derived classes MUST have names.  For one thing, CC complains
of syntax-error when the macro expands to,

     class /* no name */ : public Assoc
          {   public: 
	        (struct name_entry)& operator[] (char* key) 
	           { return *((_value_*)Assoc::lookup(key));} 
 	  }
     lookup_table;

Another problem is that the for a class to have a constructor or destructor,
the class MUST have a name, so that you can have something to name the 
constructor or destructor!

Okay, so maybe I don't campaign too hard on this second point.

mitsu@well.UUCP (Mitsuharu Hadeishi) (01/19/88)

	We've developed a set of macros for deriving from generic classes
that allows full flexibility (and even a kind of multiple inheritance)
without causing the implementor to have to define a whole bunch of
macros.  The implementor simply defines the "body" of the class as a macro,
with possible parameters a type or two and a class name.  If the
programmer wishes to avoid having to specify a class name, s/he can use
the simplest macro "Declare()" (similar to the "declare()" macro in
The Book.)  Declare(), however, is defined in terms of a series of
ever-more precise macros which allow the programmer increasing flexibility.
The "body" macro is NOT a full class declaration, only the "body" of
the class (the member functions).  If the programmer wishes to
create his/her own class derived from the base class (say, "ListElement")
s/he can simply say

	class NameNode : public ListElement
		{
		char name[40];
		public:
		// ...
		Inherit(ListElement,NameNode);
		};

	This is appropriate for those generic classes that almost always
require the addition of data members to be useful (a linked list without
any data is pretty useless.)

	We've spent a long time arguing over the names, and have come up
with a fairly simple, standard convention.  Of course, all of this will
be rendered unnecessary when and if parameterized classes are introduced
into C++; however, we find it useful for our current needs.

				-Mitsu Hadeishi
				 Electronic Arts

djones@megatest.UUCP (Dave Jones) (01/21/88)

in article <5028@well.UUCP>, mitsu@well.UUCP (Mitsuharu Hadeishi) says:
> 
> 
> 	We've developed a set of macros for deriving from generic classes
> that allows full flexibility (and even a kind of multiple inheritance)
> without causing the implementor to have to define a whole bunch of
> macros.

....

>
>

Good for you!  But I couldn't figure out what you did.  Could
you describe the macros?  Or better yet, share them with us?



	-- djones