How to call function with variable arguments at runtime?

Mr. Jonse Jonse at Theory.uni
Wed Oct 11 22:46:49 UTC 2017


On Tuesday, 10 October 2017 at 08:26:37 UTC, Marc Schütz wrote:
> On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:
>> I need to store a hetrogeneous array of delegates. How can I 
>> do this but still call the function with the appropriate 
>> number of parameters at run time?
>>
>> I have the parameters as Variant[] params and a 
>> function/delegate pointer(void* for now).
>>
>> Normally I'd push the parameters on the stack and use a call, 
>> but I'm sure D has some ability to do this, like apply(foo, 
>> args) would be the same as foo(args[0], ..., args[1]).
>>
>> I'm not concerned about type correctness, it should always be 
>> consistent between what I call and what is stored.
>>
>> Thanks.
>
> Like so?
>
> import std.variant;
>
> void foo(int a, string b, float c) {
>     import std.stdio;
>     writefln("a = %s, b = %s, c = %s", a, b, c);
> }
>
> auto apply(alias fn)(Variant[] values) {
>     import std.traits : ParameterTypeTuple;
>     import std.conv : emplace;
>     alias Types = ParameterTypeTuple!fn;
>     assert(values.length == Types.length);
>     Types args = void;
>     foreach(i, ref arg; args) {
>         // using emplace instead of assignment here to be fully 
> correct
>         emplace!(typeof(arg))(&arg, 
> values[i].get!(typeof(arg)));
>     }
>     return fn(args);
> }
>
> void main() {
>     Variant[] values = [Variant(1), Variant("Hello world"), 
> Variant(3.14159f)];
>     apply!foo(values);
> }


The problem with this is that the function parameters need to be 
known. I do not know them. All I have is a function pointer and 
the arguments in variants.


So, it would work off

void bar(int, string, float) { }


void* foo = &bar;
Variant[] values = [Variant(1), Variant("Hello world"),
Variant(3.14159f)];
apply(foo, values);

So, it has to get the type from the variant at run time and pass 
the value's appropriately.



More information about the Digitalmars-d-learn mailing list