2011-09-23 95 views
5

我有一个可变参数d式功能foo(format, ...),这是一个包装周围writefln。我想这样做:传递可变参数的一个功能到另一个功能d

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

本质上,将省略号参数传递给writefln。我知道这在C/C++中不容易/可能,但是有没有办法在D中完成这个?

+0

感谢所有,原来的模板解决这个问题非常干净和优雅。额外的好处:它不会引起任何内存分配,所以它可以从析构函数中调用(这是来自日志记录模块的函数)。 –

回答

4

这会为你做它:

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

如果你想要的模板,你可以做这样的:

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

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

但如果你想运行时可变参数,那么你必须做什么C的作用:通过_argptr的“V你的功能,例如“版本” vprintf

+0

它可以是'bar(args)'。你不应该需要'!T'。 –

+1

@JonathanMDavis:是的,我意识到这一点。但是当从另一个泛型调用泛型时,我总是明确地写它,因为它经常会使编译器错误更容易找到。(而不是说“我找不到匹配”,它实际上告诉你它无法匹配。) – Mehrdad

+0

@Mehrdad:一个值得注意的技术! – vines

4

我忘记了那些类型,即使在存在D.的variadics我不认为TDPL甚至提到他们。我认为,这使得在D.总计4种不同类型的variadics的

  1. Çvariadics使用阵列TypeInfo

    void func(string format, ...) {...} 
    
  2. 均相variadics

    extern(C) void func(string format, ...) {...} 
    
  3. d variadics

    void func(string format, string[] args...) {...} 
    
  4. 异构variadics使用模板variadics

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

我相信TDPL真的只谈论#3,#4,这些都是我正常使用的,所以我必须去挖掘到弄清楚如何使用#2传递参数。我期望这与你在#1中用C做的相似,但我不知道。

但是,它很容易与#3,#4。在这两种情况下,您只需将args传递给您想要传递给它的任何函数。和两个允许索引和切片(例如args[1]args[1 .. $])以及具有length属性。所以,它们很容易使用,而且大部分情况下,它们是更好的选择。我能想到的唯一的例外是,如果你调用一个现有的C函数(在这种情况下,你可以使用#1),或者如果你需要异构模板和无法承受的模板创建二进制文件的大小增加(其中你使用#2),这应该只是嵌入式环境中的一个问题。一般来说,#3和#4只是更好的解决方案。

+1

再往下看http://www.d-programming-language.org/function.html#variadic:#3也适用于类。 – BCS