Static if a Function Exists

WebFreak001 d.forum at webfreak.org
Fri Apr 3 07:08:03 UTC 2020


On Friday, 3 April 2020 at 01:03:01 UTC, Jonathan Levi wrote:
> I am trying to make a templated function for any arguments 
> which will work for another.
>
> Like this:
> ```
> class Cls {
>     auto opBinary(string op, T)(T b)
>     if (__traits(compiles, opBinaryImpl!op(this, b)))
>     {
>         return opBinaryImpl!op(this, b);
>     }
> }
>
> auto opBinaryImpl(string op, T)(Cls a, T b)
> if (isNumeric!T)
> {
>     // . . .
> }
> ```
>
> Here I use `__traits(compiles)` but if `opBinaryImpl` has a 
> compile error in the body than opBinary will claim it does not 
> work.
>
> I am looking for something like `__traits(signatureMatch,...)`.
>
> Using std.traits.Parameters does not work because it does not 
> work on templates nor does it work with overloading.

maybe not the optimal solution because stringof isn't properly 
defined, but currently I don't think there is a better way than:

template matchesTemplateConstraints(alias fn, Args...)
{
     enum def = fn.stringof;
     // private void testFun(string op, T)(Cls a, T b) if 
(isNumeric!T) {}
     mixin("private void testFun" ~ def[def.indexOf('(') .. $] ~ " 
{}");

     enum matchesTemplateConstraints = __traits(compiles, 
testFun!Args);
}

void main()
{
     // true
     pragma(msg, matchesTemplateConstraints!(opBinaryImpl, "+", 
int));

     // false
     pragma(msg, matchesTemplateConstraints!(opBinaryImpl, "+", 
string));
}

You can also static foreach over __traits(getOverloads, 
mixin(__MODULE__), "opBinaryImpl", true) if you have multiple 
templates of same name


More information about the Digitalmars-d-learn mailing list