On Sunday, 7 June 2020 at 23:09:41 UTC, Jack Applegame wrote:

auto const_ua = Unique!(const NonCopyable)(move(ca)); // error, why???
}
```

Moving *from* a const would violate const. At least, until such time that the compiler is finally taught about move() (hopefully, sometime this decade).

`move` and `moveEmplace` take arguments by ref. Therefore, if you call them with a const lvalue, arguments will be ref const. Which are allowed to bind to both mutable, const *and* immutable, and implementations of `move` and `moveEmplace` are not able to assume either way. Const is const.

`emplace` violates const (it has to). Perhaps `moveEmplace` should also be allowed to violate const for its *second* argument, but not the first, on the assumption that the programmer knows what they're doing.

Problem here is that, well, it wouldn't be as straightforward as it sounds, because the language allows overloading constructors based on `const` and `immutable`. So you may end up moving into a const such state that that const is not equipped to deal with:

struct S {
    private { int i; bool iAmConst; }
    this(int i) { this.i = i; }
    this(int i) const { this.i = i; iAmConst = true; }
}

S mutableS = 42;
const S constS = void;
moveEmplace(mutableS, constS); // if this was allowed, now what?
assert(constS.iAmConst);       // <- this would fail

An attempt was made to solve this (albeit the intended use case was different - impure moves), via DIP1014 and opPostMove. The DIP was even accepted. But apparently, it failed, for the above reason.

Here's hoping that move constructors do make it into the language, so that these darker places of the standard library (or rather, runtime nowadays) may die in peace.

Reply via email to