<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 12 Oct 2024 at 04:20, Jonathan M Davis via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Monday, September 30, 2024 10:05:16 AM MDT Walter Bright via Digitalmars-d <br>
wrote:<br>
> I've been implementing move constructors. They are working, at least on my<br>
> test cases so far. They are distinguished by a copy constructor takes its<br>
> argument by ref, and a move constructor by value:<br>
><br>
> ```<br>
> struct S<br>
> {<br>
> this(ref S); // copy constructor<br>
> this(S); // move constructor<br>
> }<br>
> ```<br>
> So far, so good. Consider:<br>
> ```<br>
> void phone(S s)<br>
> {<br>
> S t = s; // copy constructor<br>
> }<br>
> ```<br>
> But what if we want to initialize `t` via a move constructor? Somehow, `s`<br>
> has to be converted from an lvalue to an rvalue. This is done via the<br>
> function rvalue(): ```<br>
<br>
Given the we're now looking at having a separate syntax for move<br>
constructors, I would argue that they should just have to be ref, which<br>
should eliminate the special cases that you're fighting here.</blockquote><div><br></div><div>You really need to re-read the DIP here and understand the design principle of this whole thing.</div><div>This suggestion show us that you
either
don't understand the DIP, totally missed the point, or possibly that you fundamentally disagree with the DIP; and if that's the case, I think you need to present that argument and what you'd propose instead, rather than talk with respect to implementation of the DIP with a completely different idea in mind. If you change the fundamental substance of the DIP, it's a new DIP.</div><div></div><div><br></div><div>The proposal in the DIP is very simple; struct rvalues are ref too now, so don't worry about the ref stuff; everything's a ref. The problem to be solved is, how do we appropriately distinguish an rvalue from an lvalue; and while we've had a myriad of proposals adding attributes, Walter found an arrangement where the distinction can be expressed in existing language in an astonishingly elegant way; recognise that by-value calls (accepts rvalue) are all actually move opportunities.</div><div><br></div><div>
<div>void f(ref T) // arg is an lvalue; the syntax says "I have received a reference to <i>someone else's</i> thing"; or put another way, the callee does NOT own the argument.</div><div>void
f(T) // arg is an rvalue; this syntax says "I have received this thing"; the callee owns the argument, and as such, is a valid recipient of any move operation.<br></div><div>In order to make move operations actually move operations, they need to be passed by ref (by <i>rvalue-ref</i>, so to speak), and that is literally the entire point of the DIP; the calling convention is adjusted so a by-value (r-value) parameter is passed by rvalue-ref.<br></div><div><br></div></div><div>This is what I mean where I say we're talking about "move semantics", but everyone seems to be fixated on move constructors as if they're an extraordinarily interesting part of this story.</div><div><br></div><div>A move constructor is just an efficient initialisation opportunity, and it's a small part of the overall story regarding move semantics.</div><div><br></div><div>As I see it; the move constructor <i>must </i>be an overload; otherwise, surely you must assume the overload selection rules don't work, and so every single other function (aside from the move constructor which received a blessed hack!) will not make a proper selection.<br></div><div>Move semantics ARE proper overload selection, that's the entire meat of this design. This design <i>IS</i> overload selection rules.... to try and work that problem off to the side would be to have completely missed the point. If you exclude overload resolution from the picture, then I don't even know what we're talking about here.</div></div></div>