C++11 中的值初始化对象和 std::vector 构造函数

2021-12-21 00:00:00 vector c++ c++11

在 C++ 中,使用 C 数组而不是 std::vector 几乎没有令人信服的理由.至少在 C++03 中,少数令人信服的原因之一是不可能使用向量来分配未初始化的对象数组.std::vector 的填充"构造函数是:

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

意思是...

int* array = new array[1000000];

可能比:

std::vector<int> v(1000000);

...因为向量构造函数必须对整数数组进行零初始化.因此,当处理 POD 向量时,没有真正等效于 malloc;你能得到的最好的结果相当于 calloc.

...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 似乎改变了这一点,有了值初始化"的概念.在 C++11 中,std::vector 有一个新的构造函数,它接受一个 size_type 值,没有默认参数.此值初始化"向量中的所有元素.C++11 标准区分了值初始化"和零初始化".

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."

我的理解是值初始化"相当于在T上调用默认构造函数.如果 T 是类似于 int 的 POD 类型,那么默认构造函数只是创建一个未初始化的整数.因此,在 C++11 中,如果 T 是 POD,explicit vector::vector(size_type count) 真正等效于 malloc.

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.

然而,我对此的理解是基于草案 C++11标准,而不是最终标准.

However, my understanding of this is based on the draft C++11 standard, rather than the final standard.

问题:我的理解是否正确?如果 T 是 POD,explicit vector::vector(size_type count) 是否提供未初始化的数组(类似于 malloc)?

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?

推荐答案

问题:我的理解是否正确?explicit vector::vector(size_type count) 是否提供未初始化的数组(类似于malloc)如果T 是一个POD?

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?

没有.C++03 和 C++11 之间存在差异,但并非如此.不同的是,在C++03中,vector(N)会默认构造一个T,然后制作N个副本它来填充向量.

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.

而在 C++11 中,vector(N) 将默认构造 T N 次来填充向量.对于 POD 类型,效果是相同的.事实上,我希望几乎所有类型的效果都是相同的.然而,对于像 unique_ptr(一种仅移动类型)这样的东西,差异是至关重要的.C++03 语义永远不会工作,因为您不能复制仅移动类型.

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.

所以:

vector<unique_ptr<int>> v(10);

创建一个包含 10 个空的 unique_ptrs(它们不是彼此的副本)的向量.

creates a vector of 10 null unique_ptrs (which are not copies of each other).

在极少数情况下,它会产生影响并且您需要可以轻松实现的 C++03 行为:

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

相关文章