From: Nick Hounsome on
On 15 June, 10:05, Peng Yu <pengyu...(a)gmail.com> wrote:
> Hi,
>
> I heard that most (if not all) containers in C++ standards (including
> the upcoming one) and in boost.org do not follow copy on write
> semantics. (Please correct me if I'm wrong.)
>
> Therefore, if I need to construct some container in a function and
> return it. I'd better return a shared_ptr of the container rather than
> the container itself. For example, should return
> boost::shared_ptr<tr1::unordered_map> rather than tr1::unordered_map.
>
> If there is return value optimization (RVO), I think that I can return
> tr1::unordered_map as the compile can optimize away unnecessary coping
> in certain cases. But I think that there cases where RVO doesn't help.
> For example, if tr1::unordered_map is returned from a function that is
> only available in the object format (through linkage), the copying can
> not be avoided, right?
>
> Therefore, I think that it is always safer to return a shared_ptr
> rather the contain. Would you please let me know if my understanding
> is correct?

The new standard has rvalue references which allow efficient transfer
of data from rvalues.

This is a consumer side "optimization" and only requires the
destination to have an rvalue reference constructor.

rvalue reference constructors will simply "steal" the data from the
temporary rvalue. This is typically just a pointer swap.




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bart van Ingen Schenau on
On Jun 15, 11:05 am, Peng Yu <pengyu...(a)gmail.com> wrote:
> Hi,
>
> I heard that most (if not all) containers in C++ standards (including
> the upcoming one) and in boost.org do not follow copy on write
> semantics. (Please correct me if I'm wrong.)
>
> Therefore, if I need to construct some container in a function and
> return it. I'd better return a shared_ptr of the container rather than
> the container itself. For example, should return
> boost::shared_ptr<tr1::unordered_map> rather than tr1::unordered_map.

No, that does not follow.

>
> If there is return value optimization (RVO), I think that I can return
> tr1::unordered_map as the compile can optimize away unnecessary coping
> in certain cases. But I think that there cases where RVO doesn't help.
> For example, if tr1::unordered_map is returned from a function that is
> only available in the object format (through linkage), the copying can
> not be avoided, right?

No, that is wrong.
I do not know of any calling convention where the caller would be
affected by the application of RVO in the callee.

First, RVO is only useful for 'large' return values (more than fits in
one or two registers) and in those cases there are essentially two
ways of passing the return value:
1. The caller allocates memory for the return value and communicates
that location to the callee
2. The callee allocates memory for the return value and returns that
location.

In both cases, any copying of return values would be done in the
callee, so if (N)RVO gets applied, it only affects the callee.

>
> Therefore, I think that it is always safer to return a shared_ptr
> rather the contain. Would you please let me know if my understanding
> is correct?

Your understanding is not correct.

>
> --
> Regards,
> Peng
>
Bart v Ingen Schenau


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Jun 15, 11:05 am, Peng Yu <pengyu...(a)gmail.com> wrote:
> Hi,
>
> I heard that most (if not all) containers in C++ standards (including
> the upcoming one) and in boost.org do not follow copy on write
> semantics. (Please correct me if I'm wrong.)
>
> Therefore, if I need to construct some container in a function and
> return it. I'd better return a shared_ptr of the container rather than
> the container itself. For example, should return
> boost::shared_ptr<tr1::unordered_map> rather than tr1::unordered_map.
>
> If there is return value optimization (RVO), I think that I can return
> tr1::unordered_map as the compile can optimize away unnecessary coping
> in certain cases. But I think that there cases where RVO doesn't help.
> For example, if tr1::unordered_map is returned from a function that is
> only available in the object format (through linkage), the copying can
> not be avoided, right?

I think so, too, but you have swap method, which is efficient. So:

LibMapType map;
map.swap(LibFuncReturningMap(...));

You'd have to measure whether another map creation plus swap is faster
than going to heap (and also living with shared_ptr overhead). I'd
guess that swap is faster.

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Jun 15, 4:51 pm, Goran <goran.pu...(a)gmail.com> wrote:
> On Jun 15, 11:05 am, Peng Yu <pengyu...(a)gmail.com> wrote:
>
>
>
> > Hi,
>
> > I heard that most (if not all) containers in C++ standards (including
> > the upcoming one) and in boost.org do not follow copy on write
> > semantics. (Please correct me if I'm wrong.)
>
> > Therefore, if I need to construct some container in a function and
> > return it. I'd better return a shared_ptr of the container rather than
> > the container itself. For example, should return
> > boost::shared_ptr<tr1::unordered_map> rather than tr1::unordered_map.
>
> > If there is return value optimization (RVO), I think that I can return
> > tr1::unordered_map as the compile can optimize away unnecessary coping
> > in certain cases. But I think that there cases where RVO doesn't help.
> > For example, if tr1::unordered_map is returned from a function that is
> > only available in the object format (through linkage), the copying can
> > not be avoided, right?
>
> I think so, too, but you have swap method, which is efficient. So:
>
> LibMapType map;
> map.swap(LibFuncReturningMap(...));

And, if you are hell-bent on ...ahem... "user experience", you could
add:

inline map_type LibFuncReturningMap(other params)
{
map_type in;
LibFuncReturningMap(in, other params);
map_type out;
out.swap(in);
return out;
}

IOW, you handle "swap", and NRVO handles said user experience:

map_type m(LibFuncReturningMap(other params));

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]