Containers

Steven Schveighoffer schveiguy at gmail.com
Wed Sep 1 12:32:36 UTC 2021


On 9/1/21 7:57 AM, Paul Backus wrote:
> On Wednesday, 1 September 2021 at 11:04:41 UTC, Steven Schveighoffer wrote:
>> It's possible to forward, i.e.:
>>
>> ```d
>> template Vector(T) if (isConst!T) { alias Vector = 
>> tailconst(.Vector!(Unqual!T)); }
>> ```
>>
>> If you look at arrays, `const(T)[]` is the same as `tailconst(T[])`. 
>> This would be similar.
> 
> This runs directly into the issue 1807 problem. The compiler has to 
> recognize this specific pattern as meaningful, and if the programmer 
> writes something *semantically* equivalent using a different pattern, 
> their code will mysteriously break; e.g.,
> 
> ```d
> alias TailConstOf(T) = tailconst(T);
> alias Vector(T : const(U)) = TailConstOf!(.Vector!U);
> ```

Right, we have to fix that problem anyway.

To further explain for readers, the issue is:

```d
void foo(T)(Vector!(const(T)) arg);
```

This should accept a `Vector!(const int)` which is aliased as 
`tailconst(Vector!int)`, but the compiler can't see how to infer `T` as 
`int` from `tailconst(Vector!int)`. I think the implicit cast solution 
suffers from similar problems. It works fine if you use `const(T)[]`, 
which is the standard we should strive for.

This is one of those longstanding issues that needs addressing.

> 
> With the implicit `opCast`/constructor approach (or the `opHeadMutable` 
> approach), the compiler doesn't have to understand the relationships. It 
> just needs to know the original type and the desired type, and call the 
> appropriate user-defined function to perform the conversion.

It just means you need to handle all the implicit conversions, which is 
not trivial. The compiler already has rules for implicit const 
conversions, some of which have subtle pitfalls if you get them wrong. 
I'd rather utilize those mechanisms rather than relying on each type 
author to get them all right.

-Steve


More information about the Digitalmars-d mailing list