On 10/16/24 22:06, Arafel wrote:
> On 16/10/24 20:21, Timon Gehr wrote:
>> Yes, I think the sane design is that if you pass an lvalue to an
>> rvalue parameter, that results in a copy (during argument passing),
>> and the copy is destroyed when it goes out of scope in the constructor.
>>
>> So if you explicitly call an rvalue constructor, that would behave the
>> same as previously.
>>
>> Even with the unamended DIP1040, I think assertion failures would not
>> fire in your example. The way DIP1040 might break such code is if `S`
>> has a destructor.
>
> I guess that would be workable iff templated constructors are excluded
> from being considered move constructors, otherwise there could be cases
> where a move constructor is found that was never meant as such.
> ...
I guess the question is what else could `S(s)` reasonably do for a `S
s;`. Whether templated or not.
> Would a way of explicitly requesting a move, like `__rvalue`, be
> available in case the compiler's detection mechanism of last use needs
> to be overridden?
> ...
Yes, such mechanisms would still be needed. It is an important point as
it is easy to think move semantics just means move constructors, but it
is more than that. Perfect forwarding for rvalues is important too.
> All in all, I still see no such big benefit in changing the meaning of
> existing valid code, when adding new syntax would be much clearer all
> around.
> ...
I agree with Manu's reasoning why having `this(ref S)` and `this(S)`
work as "initialization from lvalue" and "initialization from rvalue",
corresponding to copy and move respectively would be cleaner.
But overall I don't have a strong preference, as dedicated syntax also
has some benefits. The thing I think is most important is getting the
semantics right.
Special-casing the constructor is just admitting that the overload selection mechanics are broken for **all other function calls**... It's not a matter of 'preference'; if the overload mechanics work properly then special casing the constructor wouldn't even be thinkable or raised in conversation. It's a hack; a really dumb hack which just leaves EVERY OTHER FUNCTION broken.
The fact you have "no strong preference" surprises me, maybe I've misunderstood some way in which this is not a hack that's totally broken? Can you explain to me how every other function call isn't broken under the special-case-for-move-constructor solution? Overload selection has to work, it is basically the meat of this whole thing... there's not really anything else to it.
Broken calling semantics for every function other than the constructor is not a 'compromise', it baffles me that people would even consider it.
I mean, you don't 'call' constructors so often, but you do call everything else.