Variadic functions: How to pass another variadic function the variadic args?

Ali Çehreli acehreli at yahoo.com
Sun Aug 4 08:29:47 PDT 2013


On 08/03/2013 09:05 AM, monarch_dodra wrote:

 > On Saturday, 3 August 2013 at 15:10:20 UTC, Ali Çehreli wrote:
 >> On 08/03/2013 07:58 AM, bearophile wrote:
 >>
 >> > Gabi:
 >> >
 >> >>   //HOW TO pass F1(..) the args we were called with ?
 >> >
 >> >
 >> > import std.stdio;
 >> >
 >> > void f1(Args...)(Args args) {
 >> >      foreach (arg; args)
 >> >          arg.writeln;
 >>
 >> Would you expect the following two lines behave the same?
 >>
 >>     writeln(args);
 >>     writefln("%s", args);
 >
 > I wouldn't.
 >
 >> Apparently not:
 >>
 >> 10hello1.5
 >> 10
 >>
 >> Why?
 >
 > writeln simply prints all the args it receives, then a line break.
 >
 > writefln, on the other end, only prints its single "fmt" arg. The rest
 > of the args are only used as they are referenced in fmt. Your code
 > basically boils down to:
 >
 > writefln("%s", 10, "hello", 1.5);
 > => 10

Does args have a type that makes it a single entity? If so, the two 
should behave the same. For example, the output is the same tuples and 
slices:

import std.stdio;
import std.typecons;

void foo(Args...)(Args args)
{
     // Both outputs are the same:
     writeln(tuple(1, "abc", 1.5));
     writefln("%s", tuple(1, "abc", 1.5));

     // Both outputs are the same:
     writeln([ 1, 2, 3 ]);
     writefln("%s", [ 1, 2, 3 ]);

     // Unfortunately, not here:
     writeln(args);
     writefln("%s", args);

     // Let's see why that may be...

     // Prints "(int, string, double)"
     writeln(Args.stringof);
}

void main()
{
     foo(10, "hello", 1.5);
}

According to the last line in foo(), args is three types together. Is 
that a TypeTuple I wonder... Yes, it is a TypeTuple:

import typetuple;

// ...

     // Passes
     static assert(
         is (Args == typeof(TypeTuple!(int.init, string.init, 
double.init))));

Now I see... Since writefln is also a variadic function, it naturally 
peels off the TypeTuple one %s at a time.

It is silly of me to stumble on this :) but I learned that there exists 
one type that is printed differently by the following two lines:

     writeln(a);
     writefln("%s", a);

Can you think of any other type of 'a' that would be different? (Modulo 
formatting like square brackets around slices, commas between elements, 
etc.)

Ali



More information about the Digitalmars-d-learn mailing list