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