digitalmars.D.learn - Static if a Function Exists
- Jonathan Levi (23/23) Apr 02 2020 I am trying to make a templated function for any arguments which
- WebFreak001 (25/48) Apr 03 2020 maybe not the optimal solution because stringof isn't properly
- Jonathan Levi (7/31) Apr 04 2020 I will try that out, thanks. I do have overloads, and somehow I
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.
Apr 02 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
Apr 03 2020
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.
Apr 04 2020








Jonathan Levi <catanscout gmail.com>