In C++ there are few compelling reasons to use a C array over std::vector
. One of those few compelling reasons, at least with C++03, was the fact that it is impossible to use a vector to allocate an uninitialized array of objects. The "fill" constructor for std::vector
is:
vector(size_type count, const T& value = T())
Meaning that...
int* array = new array[1000000];
is likely to be much more efficient than:
std::vector<int> v(1000000);
...since the vector constructor will have to zero-initialize the array of integers. Thus, when working with a vector of PODs, there is no real equivalent to malloc
; the best you can get is an equivalent to calloc
.
C++11 seems to have changed this, with the concept of "value-initialization." In C++11, std::vector
has a new constructor which takes a single size_type
value, with no default argument. This "value-initializes" all elements in the vector. The C++11 standard distinguishes between "value-initialization" and "zero-initialization."
My understanding is that "value-initialization" is equivalent to calling the default constructor on T
. If T
is a POD type like int
, then the default constructor simply creates an uninitialized integer. Thus, in C++11, explicit vector::vector(size_type count)
is truly equivalent to malloc
if T
is a POD.
However, my understanding of this is based on the draft C++11 standard, rather than the final standard.
Question: Is my understanding correct here? Does explicit vector::vector(size_type count)
provide an uninitialized array (similar to malloc
) if T
is a POD?
How to Initialize a Vector in C++ Using the push_back() Method. push_back() is one out of the many methods you can use to interact with vectors in C++. It takes in the new item to be passed in as a parameter. This allows us to push new items to the last index of a vector .
when you create a vector it gets default initialized, so it's up to you if you want to initialize it with user default values or not. You will always get an empty vector container if you don't initialize it.
Begin Declare v of vector type. Call push_back() function to insert values into vector v. Print “Vector elements:”. for (int a : v) print all the elements of variable a.
Question: Is my understanding correct here? Does
explicit vector::vector(size_type count)
provide an uninitialized array (similar tomalloc
) ifT
is a POD?
No. There is a difference here between C++03 and C++11, but that isn't it. The difference is that in C++03, vector<T>(N)
would default construct a T
, and then make N
copies of it to populate the vector.
Whereas in C++11, vector<T>(N)
will populate the vector by default constructing T
N
times. For POD types the effect is identical. Indeed, I would expect that for almost all types the effect is identical. However for something like a unique_ptr
(a move-only type), the difference is critical. The C++03 semantics would never work since you can not make a copy of a move-only type.
So:
vector<unique_ptr<int>> v(10);
creates a vector of 10 null unique_ptrs (which are not copies of each other).
In the rare case that it makes a difference and you need the C++03 behavior that can easily be accomplished with:
vector<T> v(10, T());
Note: the value-initialization happens in the allocator, so if you want a vector to do default initialization instead of value initialization for default constructed elements, you can do something like:
template<typename T>
struct DefaultInitAllocator {
template<typename U>
void construct(U* p)
{ ::new (static_cast<void*>(p)) U; }
template<typename U, typename... Args>
void construct(U* p, Args&&... args)
{ ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...); }
// ... rest of the allocator interface
};
// ...
typedef std::vector<int, DefaultInitAllocator<int>> DefaultInitVectorInt;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With