Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

c++ - Value-Initialized Objects in C++11 and std::vector constructor

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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?

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());

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...