Boost logo

Boost :

From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2006-03-09 19:20:45


On Mar 9, 2006, at 6:21 PM, Ralf W. Grosse-Kunstleve wrote:

> --- me22 <me22.ca_at_[hidden]> wrote:
>
>> Though that would suggest adding auto_array, which is something whose
>> use shouldn't be encouraged, imho...
>
> Could you please explain why?
>
> What is your solution for the situation in my original posting?
> Here it is
> again, this time with auto_array:
>
> auto_array<int>
> foo(unsigned size)
> {
> auto_array<int> result(new int[size]);
> // do something to result
> // if an exception is thrown result will be cleaned up
> return result;
> }
>
> void
> bar()
> {
> auto_array<int> foo_result(foo(1000));
> // code is still exception safe
> }
>
> Note that I don't want reference counting overhead (shared_array)
> or the
> overhead associated with std::vector (two pointers instead of just
> one, default
> construction on resize or lots of push_backs, deepcopy semantics).

Point your vendor at:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/
n1856.html#Addition%20-%20Class%20template%20unqiue_ptr

and tell them you want it sooner rather than later. And now I'll be
really embarrassed if your vendor is me. :-) But if it is, rattle my
cage nonetheless! :-)

According to this proposal your code would be:

   std::unique_ptr<int[]>
   foo(unsigned size)
   {
     std::unique_ptr<int[]> result(new int[size]);
     // do something to result
     // if an exception is thrown result will be cleaned up
     return result;
   }

   void
   bar()
   {
     std::unique_ptr<int[]> foo_result(foo(1000));
     // code is still exception safe
   }

In bar() (and foo()) you could access foo_result like:

foo_result[i]

but not like:

*foo_result

If you attempted a derived to base conversion:

std::unique_ptr<D[]> foo(unsigned);

void
  bar
{
     std::unique_ptr<B[]> result(foo(N));
     ...
}

then you would be stopped at compile time (C++ standard 5.3.5p3).
And release() is part of the package too. Indeed, the existence of
release() is the main advantage of unique_ptr<int[]> over vector<int>
in this proposal. The same proposal will give you shallow copy
semantics for vector as well.

   std::vector<int>
   foo(unsigned size)
   {
     std:: vector<int> result(size);
     // do something to result
     // if an exception is thrown result will be cleaned up
     return result;
   }

   void
   bar()
   {
     std::vector<int> foo_result(foo(1000)); // no deep copy of
vector possible
     // code is still exception safe
   }

 From a practical point of view, I'm not sure any compiler today will
fail to do RVO in this latter example, as long as there is only one
return statement in foo() that unambiguously refers to only one
vector declaration with auto storage (RVO is "perfect shallow
copying"). If there are multiple returns referring to different
(auto storage) vectors, then RVO will likely be defeated, but the
referenced proposal will still result in an O(1) copy of the vector
out of foo.

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk