Thread overview | |||||
---|---|---|---|---|---|
|
April 03, 2020 Static if a Function Exists | ||||
---|---|---|---|---|
| ||||
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. |
April 03, 2020 Re: Static if a Function Exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan Levi | 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 |
April 05, 2020 Re: Static if a Function Exists | ||||
---|---|---|---|---|
| ||||
Posted in reply to WebFreak001 | On Friday, 3 April 2020 at 07:08:03 UTC, WebFreak001 wrote:
> 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
I will try that out, thanks. I do have overloads, and somehow I missed the existence of `__traits(getOverloads)`.
Ah, I see, take the string of the function code (didn't know you could do that...) and create a local duplicate without the body included. Hacky, but a workable solution if D does not have anything better.
|
Copyright © 1999-2021 by the D Language Foundation