[疑难] 模板中的variadic 参数类型自动推导的问题

tuja 2007-09-30
如下面代码中,没有调用模板时,编译能通过
template test(T, R)
{
    void test(T t, R r...)
    {
        foreach(v; r)
            Stdout(v).newline;
    }
}


如果这样调用:
test("a", "b","C");

编译时就会出错,说参数个数不一致。

而用这样调用就没有问题:
test("a", "b");


这样R的参数就不能用模板泛化,笨办法是重载不同R类型的test函数。
请教有没有办法用模板实现上面示例代码的功能,而不用重载多个函数?


redsea 2007-09-30
不必使用模板,
参见 http://www.digitalmars.com/d/1.0/variadic-function-templates.html

The D Look Ma No Templates Solution

It is not practical to solve this problem in C++ without using templates. In D, one can because D supports typesafe variadic function parameters.

import std.stdio;

void print(...)
{
    foreach (arg; _arguments)
    {
writefx(stdout, (&arg)[0 .. 1], _argptr, 1);
auto size = arg.tsize();
_argptr += ((size + size_t.sizeof - 1) & ~(size_t.sizeof - 1));
    }
}


还有
import std.stdio;

class Foo { int x = 3; }
class Bar { long y = 4; }

void printargs(int x, ...)
{
    writefln("%d arguments", _arguments.length);
    for (int i = 0; i < _arguments.length; i++)
    {   _arguments[i].print();

if (_arguments[i] == typeid(int))
{
    int j = *cast(int *)_argptr;
    _argptr += int.sizeof;
    writefln("\t%d", j);
}
else if (_arguments[i] == typeid(long))
{
    long j = *cast(long *)_argptr;
    _argptr += long.sizeof;
    writefln("\t%d", j);
}
else if (_arguments[i] == typeid(double))
{
    double d = *cast(double *)_argptr;
    _argptr += double.sizeof;
    writefln("\t%g", d);
}
else if (_arguments[i] == typeid(Foo))
{
    Foo f = *cast(Foo*)_argptr;
    _argptr += Foo.sizeof;
    writefln("\t%X", f);
}
else if (_arguments[i] == typeid(Bar))
{
    Bar b = *cast(Bar*)_argptr;
    _argptr += Bar.sizeof;
    writefln("\t%X", b);
}
else
    assert(0);
    }
}

void main()
{
    Foo f = new Foo();
    Bar b = new Bar();

    writefln("%X", f);
    printargs(1, 2, 3L, 4.5, f, b);
}
oldrev 2007-09-30
template test(T, R...)
{
	void test(T t, R r)  
	{  
		foreach(v; r)  
			Stdout(v).newline
	}  
}

tuja 2007-10-01
template test(T, R...)
{
    T test(T t, R r)
    {
        foreach(v; r)
            Stdout(v).newline;
        return t;
    }
}



thx, 这个办法很优雅:
char[] s = "a";
test(s, "b", "c");

Global site tag (gtag.js) - Google Analytics