使用:

 int i;
    dprintf!"hello %s %s %s %s betty\n"(3, 4.0, &i, "abc".ptr);

重写为:

    printf("hello %d %g %p %s betty\n", 3, 4.0, &i, "abc".ptr);

import core.stdc.stdio : printf;

template Seq(A ...) { alias Seq = A; }

int dprintf(string f, A ...)(A args)
{
    enum Fmts = Formats!(A);
    enum string s = formatString(f, Fmts);
    __gshared const(char)* s2 = s.ptr;
    return printf(Seq!(s2, args[0..2], args[2..4]));
}

template Formats(T ...)
{
    static if (T.length == 0)
	enum Formats = [ ];
    else static if (T.length == 1)
	enum Formats = [Spec!(T[0])];
    else
	enum Formats = [Spec!(T[0])] ~ Formats!(T[1 .. T.length]);
}

template Spec(T : byte)    { enum Spec = "%d"; }
template Spec(T : short)   { enum Spec = "%d"; }
template Spec(T : int)     { enum Spec = "%d"; }
template Spec(T : long)    { enum Spec = "%lld"; }

template Spec(T : ubyte)   { enum Spec = "%u"; }
template Spec(T : ushort)  { enum Spec = "%u"; }
template Spec(T : uint)    { enum Spec = "%u"; }
template Spec(T : ulong)   { enum Spec = "%llu"; }

template Spec(T : float)   { enum Spec = "%g"; }
template Spec(T : double)  { enum Spec = "%g"; }
template Spec(T : real)    { enum Spec = "%Lg"; }

template Spec(T : char)    { enum Spec = "%c"; }
template Spec(T : wchar)   { enum Spec = "%c"; }
template Spec(T : dchar)   { enum Spec = "%c"; }

template Spec(T : immutable(char)*)   { enum Spec = "%s"; }
template Spec(T : const(char)*)       { enum Spec = "%s"; }
template Spec(T : T*)                 { enum Spec = "%p"; }

/******************************************
 * Replace %s format specifiers in f with corresponding specifiers in A[].
 * Other format specifiers are left as is.
 * Number of format specifiers must match A.length.
 * Params:
 *	f = printf format string
 *	A = replacement format specifiers
 * Returns:
 *	replacement printf format string
 */
string formatString(string f, string[] A ...)
{
    string r;
    size_t i;
    size_t ai;
    while (i < f.length)
    {
	if (f[i] != '%' || i + 1 == f.length)
	{
	    r ~= f[i];
	    ++i;
	    continue;
	}
	char c = f[i + 1];
	if (c == '%')
	{
	    r ~= "%%";
	    i += 2;
	    continue;
	}
	assert(ai < A.length, "not enough arguments");
	string fmt = A[ai];
	++ai;
	if (c == 's')
	{
	    r ~= fmt;
	    i += 2;
	    continue;
	}
	r ~= '%';
	++i;
	continue;
    }
    assert(ai == A.length, "not enough formats");
    return r;
}