sho@pur-phy (Sho Kuwamoto) (08/06/89)
Is there any sensible way that support for generic classes could
be added? I am new to C++ programming, and have no experience with
compiler design, so this may only be a pipe dream....
What I mean is, is could C++ be extended to allow users to make a
matrix class that could be used as a matrix of homogeneous objects?
Look at vectors. While it would be nice to use a constructor with
arguments when making a vector, the fact that you *can't* seems to
make it syntactically easier to extend this type of idea to user
defined generic classes....
What about a syntax like this? Define keywords generic and thisType:
******
generic class matrix {
int n, m;
thisType *data;
public:
matrix(int wid, int height) { n=wid; m=height; data = new thisType[n*m]; }
~matrix() { delete data; }
thisType& operator()(int j, int i) { return data[m*j+i]; }
};
class point {
int x, y;
public:
point(int startX=0, startY=0) { x = startX; y = startY; }
};
main()
{
double matrix mDouble(3,4);
int matrix mInt(3,4);
point matrix mPoint(5,5); // makes a 5x5 matrix of points, not
[...] // a matrix of points (5,5).
}
******
Since the types given in the declaration are known at compile
time, it seems that at worst, C++ could make three different classes
(double, int, point) with their names munged. What about operators?
Imagine that the following operator is a friend of matrix.
******
matrix operator+(matrix& m1, matrix& m2)
{
matrix out;
// do some error checking to make sure n&m are the same first.
for(int i=0; i < m1.n*m1.m; i++)
out = m1.data[i] + m2.data[i];
}
******
If a new version of this were made for each type, mPoint+mPoint
would be *legal* if point+point was defined, but mDouble+mInt would
not be ok since the type of the return value is ambiguous. This is
definitely a problem, but could probably be solved by some slight
changes to how user defined type conversion is done.
******
generic class matrix{
[...]
public:
double matrix(int matrix) { double matrix out; for(int i=0; ....); }
};
******
You may also need the construct,
******
double matrix operator+(double matrix& m1, int matrix& m2)
{ [...] }
******
in some cases.
What do you think? Is this too inefficient? Should I just use
void* everywhere and do explicit type conversion? Am I being a
complete idiot? (most likely) It seems to me that it would be simple
to write this if you already had something which parsed C++ correctly
(ha!). Just make a symbol table containing each class declared
generic, and make a version of that class for each type you use it
for...
-Sho
--
sho@risc.com <<-- youth wants to know.trost@crl.labs.tek.com (Bill Trost) (08/10/89)
[I was going to mail this solely to the person who asked the question, but I've brought up enough questions in my mind with it that I want to let the rest of the world beat on it] show@risc.com (Sho Kuwamoto) writes: > Is there any sensible way that support for generic classes could >be added? I am new to C++ programming, and have no experience with >compiler design, so this may only be a pipe dream.... ...and then goes on to give definitions, uses, and examples. The question is a good one, and has been discussed far and wide. After multiple inheritance, parameterized types (as they're more commonly called in the C++ community) have been the biggest things on everyone's wish lists (bigger on mine, but maybe my priorities are off :-) ). AT&T is supposed to be working on somesuch. I just hope they don't use the syntax you proposed.... Yes, I do have an alternative syntax; something like: class Stack(X) { X data; Stack(X)* next; public: void Push(); X Pop(); Stack(X)(int flag); // the constructor (I guess) Stack(int flag) // an alternative }; typedef Stack(long) StackOfLongs; typedef Stack(ostream&) StackOfStreams; typedef Stack(streamstack) StackOfStreamStacks; The syntax seems much cleaner this way (except for problems with the constructor syntax), and avoids adding a new keyword. Also, you get a generalization out of this --- there's no reason that paramaterized classes should be restricted to one parameter. A good example would be: class Assoc(left, right) { left name; right value; public: left name(); right value(); Assoc(left,right)(left l, right r); }; typedef Assoc(char*, char*) DictionaryEntry; typedef Assoc(char, (void*)()) KeyTableEntry; Of course, this opens new questions. For instance, can one overload the paramaterized type mechanism, allowing types of the same name with a different number of parameters? Should there be default parameters? What support is there for inheritance among parameterized types? Can I do, for instance: class C(X, Y) : public A(X), public B(Y) {...}; or even class E(X) : public D(F(X)) {...}; The possibilities for semantic perversion are endless. Then again, that's what C++ is all about :-). Bill Trost, Computer Research Labs, Tektronix trost@crl.labs.tek.com / tektronix!crl.labs!trost (trost@reed.bitnet, but probably tektronix!reed!trost)