Prev: Is there a preferred way of wrapping an object?
Next: return value optimization vs. returning a boost::shared_ptr of container
From: Martin B. on 14 Jun 2010 23:10 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 15 Jun 2010 05:02
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! ] |