On Tuesday, 6 July 2021 at 14:12:48 UTC, Rekel wrote:
I recently found __traits(compiles, ...) can be used in
template constraints.
(I first used `is(mixin("T.init"~op~"T2.init"))` but this cause
problems related to nanF)
However I'm wondering if there is an easier way to do what I'm
currently doing, especially since using typeof inside the
result declaration is quite cumbersome. This is a bigger
problem in my less-simplified code (using matrices), where it
starts getting slightly unreadable.
It also assumes the presence of .vec[0] (not necessarily a
problem here but it seems like a codesmell)
Simplified:
```d
template supported(A, string op, B) {
const bool supported = __traits(compiles, (A a, B b) {
mixin("return a" ~ op ~ "b;");
});
}
```
Instead of having the template evaluate to a `bool`, have it
evaluate to the type of the result:
```d
alias ResultType(Lhs, string op, Rhs) =
typeof(((Lhs lhs, Rhs rhs) => mixin("lhs", op, "rhs"))());
static assert(is(ResultType!(int, "+", double) == double));
static assert(is(ResultType!(string, "~", string) == string));
static assert(!is(ResultType!(string, "+", int))); // no valid
result type
```
Then you can use `is()` in the template constraints to check
whether the operation is supported:
```d
auto opBinary(string op, Rhs: T2[], T2) const
if (is(ResultType!(T, op, T2)))
{
Vec!(ResultType!(T, op, T2), L) result;
// etc.
}
```