difficulties with const structs and alias this / template functions

Stanislav Blinov stanislav.blinov at gmail.com
Mon Nov 19 01:13:29 UTC 2018


On Sunday, 18 November 2018 at 20:10:52 UTC, Dennis wrote:
> On Sunday, 18 November 2018 at 18:17:54 UTC, Stanislav Blinov 
> wrote:

>> Q log2(Q)(inout Q num) if (is(Q : q16) || is(Q : q32)) { /* 
>> ... */ }
>>
>> Being able to jam mutable/const/immutable implementation in 
>> one function like that should tell you that you shouldn't 
>> mutate the argument. Then, the necessity to Unqual will go 
>> away on it's own ;)
>
> Different overloads sounds like a lot of boilerplate.
> inout still results in "cannot modify `inout` expression 
> `input`"

You just dismissed that second to last sentence, did you? :)

> My goal is to be able to write straightforward and correct 
> signatures for fixed point functions that receive mutable 
> copies of whatever they are fed. This isn't even limited to my 
> custom types:
>
> ```
> T f0(T)(T x, T y) {return x += y;}
> int  f1(int  x, int  y) {return x += y;}
> long f1(long x, long y) {return x += y;}
> ```
> The explicit overloads of f1 work fine, but the generic f0 does 
> not.

```
T f0(T)(inout T x, inout T y) { return x + y; }
```

;)

But if you really really want to mutate the argument, then 
handling different mutability for T is the only way:

```
T f0(T)(T x, T y) {
     import std.traits : isMutable;
     static if (isMutable!T) return x += y;
     else return x + y;
}
```

I know it's a bit painful though. In fact, Phobos also suffers 
from it. In std.numeric:

T gcd(T)(T a, T b)
if (isIntegral!T)
{
     static if (is(T == const) || is(T == immutable))
     {
         return gcd!(Unqual!T)(a, b);
     }
     // ...
}

Not only that looks ugly, but (with DMD) it makes gcd a doulbe 
function call :D


More information about the Digitalmars-d-learn mailing list