On Monday, 28 November 2022 at 02:40:28 UTC, Tejas wrote:
On Sunday, 27 November 2022 at 17:06:31 UTC, vushu wrote:
On Saturday, 16 May 2020 at 17:45:56 UTC, Konstantin wrote:
[...]

I'm actually also very curious about this issue, since I come from c++ where this is possible, and it is a very common functionality for example for dependency inversion and dependency injection or mocking. It would be very nice to have this working.

I _think_ it's not working here because `Unique` is a `struct`, so there's no concept of inheritance here, meanwhile that it possible in `C++`

It should be possible to make template structs assignable/initializable from a compatible wrapped type with a custom constructor and a custom opAssign. There is a bit of fiddling with constraints involved to prohibit implicit casting of the wrapped type in ways that shouldn't work. See this incomplete proof of concept:

```d
interface IFoo { }
class Foo : IFoo { }

struct Unique(T) {
    T value;

// This should check that T2 is another instantiation of Unique instead of this compiles trait
    this(T2)(T2 v) if(!__traits(compiles, this.value = v.value))
    {
        this.value = v;
    }

this(T2)(Unique!T2 other) if(__traits(compiles, this.value = other.value))
    {
        this.value = other.value;
    }

    void opAssign(T2)(Unique!T2 other) {
        value = other.value;
    }
}

void main()
{
    IFoo foo = new Foo();

    Unique!IFoo f = Unique!Foo();
//Unique!IFoo f2 = Unique!int(); // error: assignment from incompaatible type
}
```

The reason why automem.Unique doesn't support this is probably hidden within the intended behavior of Unique. Maybe Adam Ruppe can shed some light on this.

Reply via email to