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

在C ++中,通过std::vector使用C数组几乎没有令人信服的理由。 至少在C ++ 03中,这些少数令人信服的理由之一就是事实上不可能使用向量来分配未初始化的对象数组。 std::vector的“fill”构造函数是:

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

意思是...

int* array = new array[1000000];

可能比以下更有效率:

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

...因为矢量构造函数将不得不初始化整数数组。 因此,在使用POD的矢量时,没有真正的等价于malloc ; 最好的你可以得到的是一个相当于calloc

C ++ 11似乎已经改变了这种情况,其中包含“值初始化”的概念。 在C ++ 11中, std::vector有一个新的构造函数, size_type接受一个size_type值,没有默认参数。 这个“值 - 初始化”向量中的所有元素。 C ++ 11标准区分“值初始化”和“零初始化”。

我的理解是,“值初始化”相当于调用T上的默认构造函数。 如果T是像int这样的POD类型,那么默认的构造函数只是简单地创建一个未初始化的整数。 因此,在C ++ 11中,如果T是POD,则explicit vector::vector(size_type count)确实等价于malloc

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

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


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

不,C ++ 03和C ++ 11之间存在差异,但事实并非如此。 不同的是,在C ++ 03中, vector<T>(N)将默认构造一个T ,然后使它的N副本填充向量。

而在C ++ 11中, vector<T>(N)将默认构造T N次。 对于POD类型,效果是相同的。 事实上,我认为几乎所有类型的效果都是相同的。 然而,对于像unique_ptr (仅限移动类型)这样的东西来说,差异至关重要。 由于您无法制作仅移动类型的副本,因此C ++ 03语义无法正常工作。

所以:

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

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

在极少数情况下,它有所作为,您需要可轻松实现的C ++ 03行为:

vector<T> v(10, T());

注意:值初始化发生在分配器中,所以如果你想要一个向量执行默认初始化而不是默认构造元素的值初始化,你可以做如下的事情:

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;
链接地址: http://www.djcxy.com/p/67785.html

上一篇: Initialized Objects in C++11 and std::vector constructor

下一篇: Behaviour of Initializer List for Array of Struct