Reputation:
I wanted to mess around with std::array
to see how different it is from std::vector
. So far, I've only found one major difference.
Sentence sentence = { "Hello", "from", "GCC", __VERSION__, "!" };
std::array<std::string, 10> a;
std::copy(sentence.begin(), sentence.end(), a.begin());
int i = 0;
for (const auto& e : a)
{
i++;
std::cout << e << std::endl;
}
std::cout << i << std::endl;
// outputs 10
i = 0;
for (const auto& e : sentence)
{
i++;
std::cout << e << std::endl;
}
std::cout << i << std::endl;
// outputs 5
for (int i = 0; i < a.size(); i++)
std::cout << i << " " << a[i] << std::endl;
// outputs 0 Hello
// ...
// 4 !
// 5-9 is blank
for (int i = 0; i < sentence.size(); i++)
std::cout << i << " " << sentence[i] << std::endl;
// outputs 0 Hello
// ...
// 4 !
// stops here
// The following outputs the same as above
i = 0;
for (auto it = a.begin(); it != a.end(); it++)
{
std::cout << i << " " << *it << std::endl;
i++;
}
std::cout << i << std::endl;
i = 0;
for (auto it = sentence.begin(); it != sentence.end(); it++)
{
std::cout << i << " " << *it << std::endl;
i++;
}
std::cout << i << std::endl;
So from what I can see, std::array
's size
and max_size
is redundant, but std::vector
's size
and capacity
can be different or the same. This is even confirmed from this quote:
size and max_size of an array object always match.
So why does std::array
have redundant size functions? More importantly, would you consider it a gotcha that std::array
's size is not necessarily the same as std::vector
's size, because the vector has a capacity? Also, does this mean that std::array
s are safe (i.e., do they have smart pointer management like vectors?)
Upvotes: 3
Views: 1680
Reputation: 16670
As you noted, a std::array
is always the same size. size() == capacity()
. That means when you create a std::array<T, 5>
, you get five calls to T
's default constructor. A std::vector<T>
, on the other hand will not default-construct any elements. Calling reserve(5)
on the vector will still not cause any items to be constructed.
Neither std::array
nor std::vector
have "smart pointer management", at least in the way I think about them. They both provide iterator types, and functions like begin/end/rbegin/rend
that let you traverse the elements in the container. When people say "smart pointer", I think about shared_ptr/unique_ptr/auto_ptr/etc
.
In general, a std::array
is stored on the stack, while a std::vector
allocates storage on the heap. In performance critical applications, that is a big advantage for std::array
. Allocating memory on the heap can be 100s or 1000s of times slower than using the stack, especially in multithreaded applications.
Upvotes: 1
Reputation: 68588
The more important difference is that std::vector
has a resize
function, whereas std::array
does not.
The size of a std::array
instance (like that of a normal array) is fixed when it is instantiated (in fact its size must be known at compile-time, and be a constant expression). A std::vector
instance however can be resized after it has been instantiated during run-time.
Further std::arrays
of different sizes are distinct types, whereas std::vectors
of different sizes are the same type.
The only reason to use a std::array
over a std::vector
, is that a std::array
uses less space and is faster. A std::vector
needs to store its size and a pointer to a heap-allocated backing store which may have extra padding to allow for resizing. A std::array
is allocated in-place (no indirect pointer), and its size
function is also known statically so a call to std::array.size()
will compile to a constant (it is a constexpr
function in fact).
Upvotes: 2
Reputation: 1698
To expand a little, on the subject an std::array
follows very closely to the actual design of an array such as char[]
in which the max-size of the array is the size of the array. This is because the array can be thought of as having an immutable size. That is a size that can not be changed besides completely reallocating the memory. Unlike a std::vector
which can be set to have a capacity
and a size that can be anywhere from 0 to that capacity
, however once it passes that capacity
value each new element will cause a complete recreation and allocation of the underlying array inside of the vector
.
Upvotes: 1
Reputation: 409146
To make it compatible with the other containers.
This way you can have a template function which takes any collection and be sure it will work the same no matter if it's a std::vector
or an std::array
.
Upvotes: 6
Reputation: 5764
capacity
in vector
is the max capacity of a vector
..which may or may not be same as its size
.
size
is the current number of elements in vector
.
For performance reasons, if you know the max size of the vector in advance (or have a guess), you can pre-determine the vector's capacity (rather than using its default value). This may significantly increase your code's performance as you would not have to reallocate on each iteration (when you add elements).
http://www.cplusplus.com/reference/vector/vector/capacity/
Upvotes: 4