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