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

Cha*_*l72 10 c++ vector c++11

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

vector(size_type count, const T& value = T())

意思是...

int* array = new array[1000000];
Run Code Online (Sandbox Code Playgroud)

可能比以下方面更有效率:

std::vector<int> v(1000000);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

How*_*ant 22

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

不.C++ 03和C++ 11之间存在差异,但事实并非如此.区别在于,在C++ 03中,vector<T>(N)默认构造a T,然后N复制它以填充向量.

而在C++ 11中,vector<T>(N)默认情况下将填充向量构造T N时间.对于POD类型,效果是相同的.实际上,我希望几乎所有类型的效果都是相同的.然而,对于像unique_ptr(仅移动类型)这样的东西,差异是至关重要的.C++ 03语义永远不会起作用,因为你无法复制仅移动类型.

所以:

vector<unique_ptr<int>> v(10);
Run Code Online (Sandbox Code Playgroud)

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

在极少数情况下它会产生影响并且您需要可以通过以下方式轻松完成的C++ 03行为:

vector<T> v(10, T());
Run Code Online (Sandbox Code Playgroud)

  • 另一个潜在的区别是,它是一个类似于共享资源的类型的向量(因此复制所有引用相同的底层资源).如果这是默认的可构造性,C++ 03将生成N个副本,所有副本都引用相同的底层资源,而C++ 11将创建N个不相关的对象. (4认同)

Nev*_*vin 7

注意:值初始化发生在分配器中,因此如果您希望向量执行默认初始化而不是默认构造元素的值初始化,您可以执行以下操作:

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;
Run Code Online (Sandbox Code Playgroud)

  • Reserve() 不允许您合法访问该空间。 (2认同)