From: Martin B. on
Peng Yu 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.)
>

No copy on write, but that's not the point I think.

The new C++0x containers are move-enabled -- basically meaning that the
container return value will not have to be copied. (Unless I'm confusing
things, this is already implemented in the std library coming with
Visual Studio 2010)

> 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.
>

shared_ptr is a significant overhead vs. code not using it. If you
already have it available and are familiar with it, it may be worth a try.
If you do it only for performance reasons, than you really have to
measure if you gain anything by it. (Which may be the case with (large)
containers of expensive-to-copy objects.)

> 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.

There are a lot of cases where RVO doesn't help and most importantly you
can't be sure if it happens unless you inspect the resulting assembly.

> (...)
> 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?
>

It's not "safer". It *may* be faster depending on the exact situation,
but you pay for it. (Complexity, dependency on boost, heap usage even
for empty collection objects, ...)

An alternative might be to just use an out parameter:
std::vector<std::string> ret_fn(); // instead of
void out_fn(std::vector<std::string> & out_param); // use this
I think it's pretty ugly most of the time, but if you really know you do
not want to copy the vector, than it's the next best thing and IMHO
certainly better than using a shared_ptr.

cheers,
Martin

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

From: Francis Glassborow on
Peng Yu 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.)

The Standard does not specify how containers shall be implemented.
However COW is rare in implementations aimed at multi-threaded code.

>
> 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.

Not really, the new move semantics is aimed at handling this transparently.
>
> 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?

No, I think you have missed the move semantics that is part of the
coming version of C++ (and, I understand, already implemented in several
compilers)

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