grauzone wrote:
Consider if opImplicitCastFrom was implemented and you had a function
"void foo(Variant[] x...)", would it be possible to pass a Variant[] to
it, that will be directly used as "x"?
For example:
void foo(Variant[] x...) {
writefln(x);
}
Variant[] t = [1,2,3];
foo(t);
Yah, in fact this compiles and runs:
import std.variant;
import std.stdio;
void foo(Variant[] x...) {
writeln(x);
}
void main()
{
auto t = variantArray(1,2,3);
foo(t);
}
Possible output 1:
[1, 2, 3]
Possible output 2:
[[1, 2, 3]]
The former is correct.
This is a slight ambiguity. Will "t" be packed into a Variant, or will
it directly assign "t" to "x" as if there wasn't an
opImplicitCastFrom(T)? Would it be a compilation error?
Anyway. If this would work, chaining function calls would be simple, and
wouldn't require additional wrapper functions.
So IMHO:
(a) Variadics with templates are good;
The "void foo(Variant[] dynatyped...)" isn't a template. But if on the
caller side you can use it as if it was a "void foo(T)(T...)" or a "void
foo(...)", everything is fine.
(b) Variadics with uniform-type arrays are good;
Sure.
(c) We should avoid variadics with void*.
Well, it isn't really important whether you use a (TypeInfo, void*)
tuple, or a Variant for passing around data of a dynamic type unknown at
compile time. Of course, Variant is much nicer.
I was only suggesting void*, because for classic variadics, it's
probably simpler to implement on the compiler side. (Although, as you
said, it's hard to convert a (TypeInfo, void*) to Variant.)
The advantage of Variant is a tad subtle. Variant is part of the
standard library and as such it's trusted code. Although it internally
uses unsafe features, it offers a safe interface. In contrast, void*
essentially trusts the application programmer.
Andrei