Getting resulting/return type from operation in templates
Paul Backus
snarwin at gmail.com
Tue Jul 6 14:27:35 UTC 2021
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.
}
```
More information about the Digitalmars-d-learn
mailing list