D - someFunc(Blah blah, Foo bar, params object[] args) - Is there any
- SL (33/33) Mar 25 2004 So let's say I have a function that I want to take an arbitrary number
- Ben Hinkle (32/32) Mar 25 2004 Posted a while back buried deep in a thread about C# is the template
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). 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 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
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