www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Runtime error trying to call opCall on variant array of objects

reply aliak <something something.com> writes:
Hey, so I'm trying to make an variant array of objects (each one 
has an opCall defined) and then call each of them in succession. 
It doesn't seem to be working. The error I get is:

"Cannot apply `()' to a value of type `Command!(__lambda1, int)". 
I think it's failing when it checks for "!isFunctionPointer!A && 
!isDelegate!A".

Here's the bit of code:

struct Command(alias fun, Args...) {
     Args args;
     this(Args args) {
         args = args;
     }
     auto opCall() {
         return fun(args);
     }
}

auto command(alias fun, Args...)(Args args) {
     return Command!(fun, Args)(args);
}

void main() {
     auto commands = variantArray(
         command!(a => a + 1)(1),
         command!(a => a + 2)(1),
         command!(a => a + 3)(1),
     );

    // commands.each!(a => a()); // <-- crashes runtime

     typeid(commands[0]).writeln; // 
std.variant.VariantN!32LU.VariantN

     auto cmd = command!(a => a + 1)(1);
     typeid(cmd).writeln; // scratchpad.main.Command!(__lambda4, 
int).Command
}

Is there a way to do what I'm trying to do?

Cheers!
Dec 24 2016
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/24/2016 08:36 AM, aliak wrote:

 "Cannot apply `()' to a value of type `Command!(__lambda1, int)". I
 think it's failing when it checks for "!isFunctionPointer!A &&
 !isDelegate!A".
Storing delegates is a workaround. Three notes in the code: // (1) Added imports import std.variant; import std.stdio; import std.algorithm; struct Command(alias fun, Args...) { Args args; this(Args args) { this.args = args; /* (2) args = args was a common mistake. * dmd, please warn about this one. * (I think there is a bug about that.) */ } auto opCall() { writefln("opCall called for %s", args); return fun(args); } } auto command(alias fun, Args...)(Args args) { auto c = Command!(fun, Args)(args); writefln("Created %s", c); // (3) Workaround: Storing delegates, not Command instances. return () => c(); } void main() { auto commands = variantArray( command!(a => a + 1)(1), command!(a => a + 2)(1), command!(a => a + 3)(1), ); commands.each!(a => a()); typeid(commands[0]).writeln; // std.variant.VariantN!32LU.VariantN auto cmd = command!(a => a + 1)(1); typeid(cmd).writeln; // scratchpad.main.Command!(__lambda4, int).Command } Alid
Dec 24 2016
parent aliak <something something.com> writes:
On Saturday, 24 December 2016 at 23:06:25 UTC, Ali Çehreli wrote:
     auto c = Command!(fun, Args)(args);
     writefln("Created %s", c);
     // (3) Workaround: Storing delegates, not Command instances.
     return () => c();
Ah, yes. Nice work around :) Thankies!
Dec 25 2016