とおもったらニュースグループにそのものずばりの記事があったよ。
- Re: Variable length arguement lists in D(http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/1875)
std.c.stdargってなに?ってこれ0.88でPhobosに追加されたのか。知らないよ。
だがこれうまく動かせない。とりあえず記事に投稿されているものはちゃんと動作する。しかし、別モジュールのテンプレートを組み合わせたクラス内で利用して、インスタンス化しようとすると、なぜかリンカがエラーを吐く。たとえば、foo.dとして、
private import std.c.stdarg; public class Foo(T) { int foo(char *x, ...) { va_list ap; va_start!(typeof(x))(ap, x); printf("&x = %p, ap = %p\n", &x, ap); T i; i = va_arg!(typeof(i))(ap); printf("i = %d\n", i); long l; l = va_arg!(typeof(l))(ap); printf("l = %lld\n", l); uint k; k = va_arg!(typeof(k))(ap); printf("k = %u\n", k); va_end(ap); return i + l + k; } }
としておき、これをインスタンス化するbar.dを、
private import foo; void main() { int j; Foo!(int) foo = new Foo!(int); j = foo.foo("hello", 3, 23L, 4); printf("j = %d\n", j); assert(j == 30); }
とすると、bar.objで'Symbol Undefined'とリンカが文句を言う。ちなみにfoo.d内で'alias Foo!(int) Fooint'のようにエイリアスしてしまうと文句は言わなくなる。要するに別モジュールでテンプレートを解決しようとすると怒るらしい。
stdarg.d自体もテンプレートで動作を実現しているので、この辺で何かが衝突してるのかなあ。やっぱりテンプレートよく分からないよ...