<div dir="ltr"><div>Ohhh man, that was a grueling slog getting through the sea of people casually adding some opinion on the flavour of a new keyword, while completely skipping over the premise of the proposition...</div><br><div>Sorry Walter, I think it's a very bad idea, and unlike everyone else here apparently, I want to see clear evidence that this path is the only reasonable solution before I even consider weighing on the colour of this bikeshed...<br></div><div><br></div><div>Please show some fail cases so we can actually consider the problem?<br></div><div><br></div><div>Why can't a constructor be selected by normal overload resolution rules?</div><div>And why should a copy or a move constructor be special or distinct from a "regular constructor" as you call it? Can you show some cases where the distinction is necessary?<br></div><div><br></div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 9 Oct 2024 at 15:42, Manu <<a href="mailto:turkeyman@gmail.com">turkeyman@gmail.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"><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 6 Oct 2024 at 14:06, Walter Bright via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com" target="_blank">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">```<br>
struct S { ... }<br>
<br>
this(ref S) // copy constructor<br>
this(this)  // postblit<br>
this(S)     // move constructor<br>
~this()     // destructor<br>
<br>
alias T = S;<br>
this(T);    // also move constructor<br>
<br>
alias Q = int;<br>
this(Q);    // regular constructor<br>
```<br>
As the above illustrates, a move constructor cannot be distinguished from a <br>
regular constructor by syntax alone. It needs semantic analysis.<br></blockquote><div><br></div><div>Yes, I would expect this.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
While this seems simple enough, it isn't I have discovered to my chagrin. The <br>
overload rules in the language (including things like rvalue references where <br>
sometimes an rvalue becomes an lvalue) that the move constructors get confused <br>
with the copy constructors, leading to recursive semantic loops and other problems.<br>
<br>
I've struggled with this for days now.<br></blockquote><div><br></div><div>Can you show us some cases?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A fix that would simplify the language and the compiler would be to have a <br>
unique syntax for a move constructor, instead of the ambiguous one in the <br>
proposal. That way, searching for a copy constructor will only yield copy <br>
constructors, and searching for a move constructor will only yield move <br>
constructors. There will be a sharp distinction between them, even in the source <br>
code. (I have seen code so dense with templates it is hard to figure out what <br>
kind of constructor it is.)<br>
<br>
Something like one of:<br>
```<br>
1. =this(S)<br>
2. this(=S)<br>
3. <-this(S)<br>
```<br>
?<br>
<br>
It may take a bit of getting used to. I kinda prefer (1) as it is sorta like <br>
`~this()`.<br></blockquote><div><br></div><div>It's not right to distinguish move constructors, by-value argument is a potential move opportunity.<br></div><div></div><div>Why aren't the regular parameter matching semantics sufficient? Can you please give us a set of examples where the regular parameter matching semantics are failing or infinite-looping?<br></div><div><br></div><div><br></div><div>The story you present is incomplete, let me enhance:</div><div><br></div><div>
struct S { ... }</div><div>struct Other { ... }<br></div><div>
<br>
this(ref S) // copy constructor<br>
this(this)  // postblit<br>
this(S)     // move constructor<br>
~this()     // destructor<br>
</div><div>
<div><br></div><div>this(Other) // move from other (Other is an rvalue here)<br></div><div>this(ref Other) // copy from other (Other is obviously a ref)<br></div><div><br></div><br></div><div>Likewise, I don't understand why opMove would be necessary to distinguish from opAssign?</div><div>If you introduce opMove, then you'll end up with opIndexMove, opOpMove, etc.</div><div>Is that something you want? Assuming you want to avoid this; then I also imagine solving for that issue would equally solve for the main constructor case?</div></div></div>
</blockquote></div></div>