On Tuesday, 27 March 2018 at 18:14:18 UTC, Manu wrote:
On 27 March 2018 at 00:14, Atila Neves via Digitalmars-d <[email protected]> wrote:
On Monday, 26 March 2018 at 19:24:13 UTC, Manu wrote:

On 26 March 2018 at 07:40, Atila Neves via Digitalmars-d <[email protected]> wrote:

On Friday, 23 March 2018 at 22:01:44 UTC, Manu wrote:


That's _if_ T is big and _if_ it even gets copied,

You've just described the exact anatomy of a ref function!
You wouldn't write a function to receive T by ref UNLESS T was both big, and the function probably won't inline (therefore definitely copy), and that condition will be triggered by any of the list of reasons I've said a bunch of times (extern, dll, lib, virtual, etc). People don't just love writing ref (well, some people might), but they use it deliberately, typically in user-facing boundary API's for these
exact reasons.

I know. I was arguing that those cases are uncommon and the API pain is therefore not too big of an issue. I'm pretty sure that you feel it more because of what you write in D.

Right. I'm talking about deliberate use of ref... Or *existing*
(deliberate) use of ref, as is the case in almost all my my cases. The
code already exists.

Right, and I was assuming (perhaps incorrectly) that this existing code was C++, hence me being on board with binding rvalues to const ref there.

Only if you ARE moving, and not copying. D must deep copy too if you
actually copy.
Your example assumes C++ doesn't have a move constructor. D has
implicit move semantics, so you can only make an equivalent comparison where C++ also defines the move constructor so the move case doesn't
pollute the ref comparison.

I wasn't assuming the lack of a move constructor. What I was saying is that passing by value in C++ will usually mean a copy, whereas in D it usually means a move.

Also, irrespective of whether move semantics are performed (eliding potential deep copying, as in your example), the binary memcpy still has to be performed when handling values by-val, unless RVO (we're not talking about return values), or inlining is able to eliminate it.

Good point about memcpy.

In C++'s case, it's not that references were deficient at being references that C++ needed rval-references, it's that references were deficient at being move-able.


There were deficient at being moveable because temporaries can bind to const T&.

... what? That's just not true at all.
If temporaries couldn't bind to C++ ref, then you *definitely*
wouldn't be able to move it, because you can guarantee that someone
else owns the reference.

Precisely. That's how D works.


rvalue references were introduced in C++ to capture the calls with rvalues into a separate function call, exactly the same way as the by-value overload will catch the rvalues in D (and perform an implicit
move).

Yes.

It was impossible for C++ to implement D's implicit move semantics
when receiving by-value for reasons that have nothing to do with
references; C++ allows interior pointers which breaks implicit moving, C++ can overload default constructor which also breaks implicit moving
(no implicit way to reset the state of the prior owner).

I hadn't thought about the implications of interior pointers. Very good point.

References have no interaction with move semantics.

Even given interior pointers, I disagree.

But again, we're not talking about move semantics here, we're just talking about references ;)

See comment above ;)

I'd love to know what that would look like.

That's exactly what I've been saying. For like, 9 years..
It looks like this:
https://github.com/TurkeyMan/DIPs/blob/ref_args/DIPs/DIP1xxx-rval_to_ref.md
 (contribution appreciated)

I was unaware of this (or I forgot). After reading it I'm not sure of what corner cases might arise, but if I'm getting it right I think it could work.

And as far as I
can tell, it basically only affects me, because I do so much work
against established C++ code! >_<

That's entirely possible. I can use my fingers to count the number of times I've written `extern(C++)`.

Atila


Reply via email to