开发者

Passing variadic arguments in one function to another function in D

开发者 https://www.devze.com 2023-04-08 14:05 出处:网络
I have a variadic D-style function foo(format, ...), which is a wrapper around writefln. I\'d like to do something like this:

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, <...>)开发者_StackOverflow {
    //...
    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?


This will do it for you:

import std.stdio;
void customWrite(Args...)(string format, Args args)
{
    writefln(format, args);
}


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.


If you want templates, you can do it like this:

auto bar(T...)(T args) { ... }

auto foo(T...)(T args)
{
    return bar!T(args);
}

but if you want run-time variadic arguments, then you have to do what C does: pass _argptr to the "v-version" of your function, e.g. vprintf.

0

精彩评论

暂无评论...
验证码 换一张
取 消