std::vector vs std::unique_ptr

Started by
27 comments, last by rnlf_in_space 11 years, 9 months ago
I am trying to understand the changes and differences with some of the smart pointers and containers. Using the vector form of std::unique_ptr<T[]> has some overlapping functionality with std::vector. What are the general guidelines here? What I think, is:

std::unique_ptr

  • is better to use when you want to transfer ownership
  • has no overhead (memory or CPU)

std::vector:

  • is better when the initial size is unknown as it allows for dynamic growth
  • keeps track of the size for you

Am I missing something?
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/
Advertisement
First of all, the title of this message is very misleading.

What you actually want to know is the difference between an array which life time is managed with unique_ptr vs. std::vector.

Fortunately there is a good general guideline:
Use std::vector!

If you need to know why, please search for some of the discussion about arrays vs. vector and remove all arguments against arrays that concern lifetime management of the array's memory.
I concur.

Thou shall never manage arrays through anything but std::vector<>.

For one, the std::default_deleter (that you don't want to change, otherwise you manager a std::unique_ptr<T,Deleter> instead of a std::unique_ptr<T>) performs a delete on the underlying object, while you'll want a delete[].

Second, std::vector<> is a smart pointer for arrays. There is no need for anything else.
I'm pretty sure the default deleter does a delete[] on array unique_ptr's. The template is specialized for array types.

Anyway, transferring ownership is pretty easy with a vector too. If you return a vector created in the same function, it'll actually trigger the move semantics, resulting in only the pointer to the contents being moved to the new vector "copy" outside the function. That means the move takes constant time no matter how big a vector.

To force move semantics, you use the std::move function. This effectively transfers ownership the same way.

Only difference is that the unique_ptr enforces the ownership a bit more by not being implicitly copyable.

Very few occations call for a C array (with or without unique_ptr), and if you actually need a constant sized container, use the new std::array rather than a C-array. The std::array can be entirely stack allocated as well since it's constant sized, which is pretty handy at times.

I'm pretty sure the default deleter does a delete[] on array unique_ptr's. The template is specialized for array types.

You are correct.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Thanks for some feed-back, but there is still no explanation on why I should use std::vector instead of std::unique_ptr for managing vectors.

If that is the case, then there is the question why there is a std::unique_ptr for managing vectors?

Edit: Well, there is one argument (and some added facts) from Zoomulator:

[background=rgb(250, 251, 252)]Only difference is that the unique_ptr enforces the ownership a bit more by not being implicitly copyable.[/quote][/background]

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

First of all, the title of this message is very misleading.

Please explain in what way it is misleading? std::vector is used to manage vectors. std::unique_ptr is used to manage pointers to objects or vectors. So it is rather obvious what I was asking for, isn't it?

Fortunately there is a good general guideline:
Use std::vector!

If you need to know why, please search for some of the discussion about arrays vs. vector and remove all arguments against arrays that concern lifetime management of the array's memory.
[/quote]
I don't understand this. A vector is a one dimensional array. So for the one dimensional case, there are no differences by definition.
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

Thanks for some feed-back, but there is still no explanation on why I should use std::vector instead of std::unique_ptr for managing vectors.

  • You have a size(). With a unique_ptr<T[]> you have to keep a size along side it
  • You have a richer interface. T[] doesn't give you a whole lot out the box.
  • You can add/remove elements after you've decided the initial array size
  • std::vector can be moved/swapped if need be.
  • std::vector can be copied

In fact, there really isn't much overlap between std::vector and unique_ptr<T[]> besides the indexing operator.

Does unique_ptr<T[]> support construction from an initializer list? If not, there's another important difference.
A vector is a first-class object. The contiguous memory handled by a unique_ptr is not. A vector has copy semantics by default, a unique_ptr has move semantics by default. It's all the difference in the world, even if they both just deal with ways to access dynamically-allocated contiguous regions of memory.

Stephen M. Webb
Professional Free Software Developer

So, it looks like std::vector supports everything I can do with std::unique_ptr<T[]>, and more. And you usually want to keep size information for a vector, anyway.

I tested with a function that defined a local std::vector, initialized it, and then returned it. Initializing a variable with the result of this function did indeed reference the same memory area, which means there was an implicit move. I wonder how that works (though it did what I wanted). Anyway, I get the ownership defined, automatic memory management, and the source/sink functionality to work.

One use-case I have, is to create a vector of data that need to be temporarily forwarded externally (in this case a vertex attribute list forwarded to an OpenGL VBO). Using std::unique_ptr, I can use the get() function to get a pointer. Is it allowed to use &v[0], where v is a std::vector?

It seems to me then that the advantage of std::unique_ptr (compared to std::vector) is when you want to ensure it is not copied?
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

This topic is closed to new replies.

Advertisement