How to write a counterpart to C++ std::invoke that works with both free functions and methods?

Adam D. Ruppe destructionator at gmail.com
Sat Sep 26 23:23:13 UTC 2020


On Saturday, 26 September 2020 at 22:58:44 UTC, 60rntogo wrote:
> I get the error "undefined identifier isValid". How can I make 
> this work?

This part is easy, you need to give the name like

assert(invoke!(Foo.isValid)(foo, 3));


Now, the other part is tricky, and a new feature just released 
this week is there to help:

https://dlang.org/changelog/2.094.0.html#add_traits_child

So you use this to branch on static vs non-static functions:

auto invoke(alias fun, Args...)(Args args)
{
   static if(__traits(isStaticFunction, fun))
     return fun(args);
   else
     return __traits(child, args[0], fun)(args[1 .. $]);
}


So, for static functions, you won't be passing a `this`, so it 
just sends the args straight in.

But for non-static functions, you use the now trait to attach 
`this` to the given function, then pass the rest of the arguments 
normally.

As a result, you `add` works fine, and 
`assert(invoke!(Foo.isValid)(foo, 3));` now works too!


More information about the Digitalmars-d-learn mailing list