www.digitalmars.com         C & C++   DMDScript  

D - someFunc(Blah blah, Foo bar, params object[] args) - Is there any

reply SL <shadowlord13 users.sourceforge.net> writes:
So let's say I have a function that I want to take an arbitrary number 
of arguments. Actually, I do, so I'll get specific. The function's name 
is TableRow, and its first argument is a StreamSocket, and after that it 
takes an arbitrary number of args, converts them all to strings (if they 
aren't already), and constructs a table row in HTML (writing it into a 
string) and sends it to the StreamSocket (which is connected to a 
web-browser).

'params' is a keyword in C# which indicates to the compiler that someone 
can call this function with an arbitrary number of arguments (after all 
the required ones to the left of the params argument), and they'll be 
corralled into an array which the function will use. Technically this 
doesn't add special code to the function with params - it just expects 
an array for that argument - It tells the compiler to do evil things to 
all the code which *calls* that function, to make it corral all the 
arguments it wants to send into an array and use that as a parameter.

In c++ I'd have had to do some voodoo with va_something_or_other which I 
never fully understood; The C# way makes far more sense to me (Although 
the way it's implemented seems slightly odd to me).

In any event, I didn't happen to notice anything like this in the D 
spec, so I figured I'd ask here: Does anything like this exist in D? If 
not, are there plans to have such a thing? (In the mean-time, I can try 
to write TableRow(s, [p.orbit, p.sendheat, p.gas, p.h2o, p.water, p.ice, 
p.vapor, p.land, p.heat, p.surfaceArea, p.volume, p.mass]); instead of 
TableRow(s, p.orbit, p.sendheat, p.gas, p.h2o, p.water, p.ice, p.vapor, 
p.land, p.heat, p.surfaceArea, p.volume, p.mass); :P )

Hmmm. And now it occurs to me that I probably have to do 
TableRow(StreamSocket, char[][]) as well as TableRow(StreamSocket, 
real[]) and can't do TableRow(StreamSocket, object[]) and call 
toString() on it, since real etc don't have toString members ooorr.... 
Hmmmm. Is real/int/double/etc even descended from object in D? (Probably 
not, right?)

Thanks,
-SL
Mar 25 2004
parent Ben Hinkle <bhinkle4 juno.com> writes:
Posted a while back buried deep in a thread about C# is the template

private import std.c.stdio;
template va_array(T:T[])
{
   T[] va_array(uint* ptr)
   {
      T* args = cast(T*)(cast(va_list)ptr + uint.size);
      return args[0 .. *ptr];
   }
}

(well, actually I modified the declaration a tiny bit)
To use it pass the number of args and then just list the arguments
making sure they are the right type. For example:

void
someFunc(int x, double y, uint num_args, ...)
{
   char[][] args = va_array!(char[][])(&num_args);
   // do whatever you want with args
   foreach (char[] str; args)
      printf("%.*s\n",str);
}

int
main()
{
    someFunc(0,1.0,3,"hello","world","goodbye");
    return 0;
}

This will call someFunc with 3 strings which someFunc packages up
into a dynamic array of char[] - and on the plus side it doesn't
allocate any memory. If you want to use the args array after
someFunc returns you can just .dup it.

-Ben
Mar 25 2004