簡體   English   中英

C ++ 11和std :: vector構造函數中的值初始化對象

[英]Value-Initialized Objects in C++11 and std::vector constructor

在C ++中,使用C數組而不是std::vector幾乎沒有令人信服的理由。 其中一個令人信服的原因,至少在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值,沒有默認參數。 這個“初始化”向量中的所有元素。 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM