[comp.lang.c++] Initializer in C++

pcb@usl.usl.edu (Peter C. Bahrs) (02/06/89)

In standard C we have the ability to initialize arrays such as:
  
   int x[] = {1,2,3};
and
   static int x[2][3] = {{1,2,3},{4,5,6}};
etc...

I would like to have a class such as ARRAY (actually matrix) that
takes initializers...
   ARRAY x(2,3)={{1,2,3},{4,5,6}};

So the construct would?? be someting like:
   ARRAY (int r, int c)
   {
      allocate the buf to be r by c...
   }
And now I guess the operator= would be:
   void operator=(int *s)
    {
     now loop through and let each buf[i][j] = *s
      and then s++
    }
This is as close as I have come, however it doesn't work, the operator=
never gets called.  Maybe the constructor should take another parameter???

Does anyone have an idea?  
Thanks in advance.

pcb@usl.usl.edu

jeenglis@nunki.usc.edu (Joe English) (02/07/89)

pcb@usl.usl.edu (Peter C. Bahrs) writes:
>In standard C we have the ability to initialize arrays such as:
>  
>   int x[] = {1,2,3};
>and
>   static int x[2][3] = {{1,2,3},{4,5,6}};
>etc...
>
>I would like to have a class such as ARRAY (actually matrix) that
>takes initializers...
>   ARRAY x(2,3)={{1,2,3},{4,5,6}};
>
>So the construct would?? be someting like:
>   ARRAY (int r, int c)
>   {
>      allocate the buf to be r by c...
>   }
>And now I guess the operator= would be:
>   void operator=(int *s)
>    {
>     now loop through and let each buf[i][j] = *s
>      and then s++
>    }
>This is as close as I have come, however it doesn't work, the operator=
>never gets called.  Maybe the constructor should take another parameter???

operator= is only called when an assignment is made to an
*already initialized* object.  In the case of an initializer
like "SomeClass Foo = Bar;" what gets called is
SomeClass::Someclass(typeof(Bar)), if it exists.  I'm not sure
if your example is legal -- can you use both initializer forms
in the same statement, like "SomeClass Foo(diddle,wubba) = Bar;" ?

You're right, you need to add another parameter to the
constructor, to take the values of the array.  However, you
can't write ARRAY x(2,3,{{...},{...}}); since it's not
possible to declare aggregate or array constants other than
strings (I think**).  You'll still have to declare a static
int[][] to hold the values (since this can take an aggregate 
initializer) and pass it to the constructor.

(**Or is it possible in C++ yet?  If so, I haven't heard about it.
 The lack of support for aggregate constants is being discussed in 
 comp.lang.c right now.)


--Joe English

  jeenglis@nunki.usc.edu

trent@psu-cs.UUCP (Trent A. Fisher) (02/16/89)

pcb@usl.usl.edu (Peter C. Bahrs) writes:
>In standard C we have the ability to initialize arrays such as:
>  
>   int x[] = {1,2,3};
>and
>   static int x[2][3] = {{1,2,3},{4,5,6}};
>etc...
>
>I would like to have a class such as ARRAY (actually matrix) that
>takes initializers...
>   ARRAY x(2,3)={{1,2,3},{4,5,6}};
>
>So the construct would?? be someting like:
>  [ possible constructors... ]

When I was working on a Matrix class a few months ago, I wanted to do
this same thing, after several days of trying different things,
I assumed that what jeenglis@nunki.usc.edu (Joe English) pointed out was true:
>
>I'm not sure
>if your example is legal -- can you use both initializer forms
>in the same statement, like "SomeClass Foo(diddle,wubba) = Bar;" ?
>

I wanted to be able to set Matrixes in some simple, and brief way
(so for loops were out).

First* I tried to create a constructor like this:
	Matrix(int rows, int cols, double*);

(* acctually I tried 2D arrays first, with no success).

With this I was hoping I could so something like this:

	Matrix  m(3,3,
			{ 1.0, 2.0, 3.0,
			  4.0, 5.0, 6.0,
			  7.0, 8.0, 9.0 });

Or this:
	double	x[] = { 1.0, 2.0, 3.0,
			4.0, 5.0, 6.0,
			7.0, 8.0, 9.0 };
	Matrix  m(3,3,x);

But, I discovered what jeenglis@nunki.usc.edu (Joe English) pointed out:
>
>You're right, you need to add another parameter to the
>constructor, to take the values of the array.  However, you
>can't write ARRAY x(2,3,{{...},{...}}); since it's not
>possible to declare aggregate or array constants other than
>strings (I think**).  You'll still have to declare a static
>int[][] to hold the values (since this can take an aggregate 
>initializer) and pass it to the constructor.
>

Since the thought of declaring all these double arrays externally
didn't sit well with me, I tried to think of other alternatives.
All I could think of was using <stdargs.h>, so I made a constructor like so:
	Matrix(int rows, int cols, double, ...);

Then I tried the following in my code:
        Matrix ident(3,3,
                        1.0, 0.0, 0.0,
                        0.0, 1.0, 0.0,
                        0.0, 0.0, 1.0);

This worked, except for one hitch: all the numbers have to be explicit
double's, otherwise the constructor will try and read doubles off the stack,
but integers were put there...

That's my kludge to solve this problem, I thought it was the best solution
(in terms of the code making and using the Matrixes).

It would be nice if a more elegant constructor would work,
preferably the one that pcb@usl.usl.edu (Peter C. Bahrs) wanted to use.
Will something like this *ever* work??

BTW, If anyone wants the source for my Matrix class, send me mail...

+-----------------------------------------------------------------------------+
| Trent A. Fisher, Assistant SysAdmin                  trent@psu-cs   (LOCAL) |
| Portland State University CS                     trent@cs.pdx.edu   (CSNET) |
| Portland Center for Advanced        trent%cs.pdx.edu@relay.cs.net (ARPANET) |
| Technology           {uunet,ucbvax,gatech}!tektronix!psu-cs!trent    (UUCP) |
| Room 142                     P.O. Box 751 Portland, OR 97207-0751    (USPS) |
+-----------------------------------------------------------------------------+
   "Don't ask me how it works, or I'll start to whimper." -- Arthur Dent
===============================================================================