How to write a counterpart to C++ std::invoke that works with both free functions and methods?
60rntogo
60rntogo at gmail.com
Sun Oct 4 08:55:44 UTC 2020
On Tuesday, 29 September 2020 at 01:19:48 UTC, Adam D. Ruppe
wrote:
> On Sunday, 27 September 2020 at 05:22:36 UTC, 60rntogo wrote:
>> How would I check if it is actually a free function?
>>
>> but this doesn't even compile since I defined add inside my
>> main function
>
> aaaaah that's not a free function!!
OK, I see. That makes sense I suppose. Thanks for putting this
together, but I'm afraid that I managed to break it again and
this time it is really baffling.
---
module foo;
auto invoke(alias fun, Args...)(Args args)
{
static if(__traits(isStaticFunction, fun) || __traits(isNested,
fun))
return fun(args);
else
return __traits(child, args[0], fun)(args[1 .. $]);
}
unittest
{
import std : approxEqual;
assert(invoke!approxEqual(2.0, 2.001));
}
---
This gives me these errors:
---
source/foo.d(6,48): Error: aggregate or function expected instead
of approxEqual(T, U, V)(T value, U reference, V maxRelDiff =
0.01, V maxAbsDiff = 1e-05)
source/foo.d(9,41): Error: template std.math.approxEqual cannot
deduce function from argument types !()(double), candidates are:
/usr/include/dmd/phobos/std/math.d(8479,6): approxEqual(T,
U, V)(T value, U reference, V maxRelDiff = 0.01, V maxAbsDiff =
1e-05)
source/foo.d(15,28): Error: template instance
foo.invoke!(approxEqual, double, double) error instantiating
---
Confusingly, these errors disappear if I include the unit test in
my main file (i.e., just add it to the code you posted) rather
than foo.d or if I use a function like add defined in the module
instead of imported approxEqual. Any ideas?
More information about the Digitalmars-d-learn
mailing list