Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing variadic arguments in one function to another function in D

I have a variadic D-style function foo(format, ...), which is a wrapper around writefln. I'd like to do something like this:

foo(format, <...>) {
    //...
    writefln(format, ...);
}

Essentially, passing on the ellipsis parameter(s) to writefln. I understand that this isn't easy/possible in C/C++, but is there a way to accomplish this in D?

like image 274
Mark LeMoine Avatar asked Sep 23 '11 20:09

Mark LeMoine


2 Answers

This will do it for you:

import std.stdio;
void customWrite(Args...)(string format, Args args)
{
    writefln(format, args);
}
like image 93
Justin W Avatar answered Sep 28 '22 14:09

Justin W


I had forgotten that those type of variadics even existed in D. I don't think that TDPL even mentions them. I believe that that makes a grand total of 4 different types of variadics in D.

  1. C variadics

    extern(C) void func(string format, ...) {...}
    
  2. D variadics with TypeInfo

    void func(string format, ...) {...}
    
  3. Homogeneous variadics using arrays

    void func(string format, string[] args...) {...}
    
  4. Heterogeneous variadics using template variadics

    void func(T...)(string format, args) {...}
    

I believe that TDPL really only talks about #3 and #4, and those are all that I normally use, so I'd have to go digging to figure out how to pass arguments using #2. I expect that it's similar to how you do it in C with #1, but I don't know.

However, it's easy with #3 and #4. In both cases, you just pass args to whatever function you want to pass it to. And both allow for indexing and slicing (e.g. args[1] and args[1 .. $]) as well as having a length property. So, they're easy to use, and for the most part, they're the better way to go. The only exceptions that I can think of are if you're calling an existing C function (in which case, you use #1) or if you need heterogeneous templates and can't afford the increase in binary size that templates create (in which case you use #2), which should really only be an issue in embedded environments. In general, #3 and #4 and just plain better solutions.

like image 30
Jonathan M Davis Avatar answered Sep 28 '22 15:09

Jonathan M Davis