2016-07-26 111 views
2

請參見下面的代碼:初始化列表在C++中

std::vector<int> v1{1, 2, 3}; 
std::vector<int> v2 = {1, 2, 3}; 

我的問題是:

  1. 是兩者之間有什麼區別?我知道第一個必須是列表初始化,但第二個怎麼樣?

  2. 由於不存在第二個是分配的跡象,這讓我覺得,編譯器將使用std::initializer_list首先創建一個臨時vector,然後用它的拷貝構造函數來複制vector臨時到v2。這是事實嗎?

回答

8

這兩個(direct-list-initialization vs copy-list-initialization)在這種情況下是完全一樣的。沒有構建臨時的std::vector,並且沒有調用std::vector::operator=。等號是初始化語法的一部分。

會有區別,如果std::vector's constructor overload no. 7被標記explicit,在這種情況下,任何副本初始化失敗,但是這將是在標準庫的設計缺陷。

+0

因此,兩者都屬於列表初始化,它們與複製初始化沒有關聯,對嗎? – zhangzhimin

+0

* copy-list-initialization *是根據* copy-initialization *定義的。我已經使用* copy-initialization *來推廣一下。 – LogicStuff

8

它們都是list initialization(自C++ 11以來),第一個是直接列表初始化,第二個是複製列表初始化。

  1. 這兩者有什麼區別嗎?

對於直接列表初始化顯式和非顯式的構造將被考慮,而副本列表初始化唯一的非顯式的構造可能會被調用。對於這種情況(即std::vector),實際結果是相同的。

  • 因爲存在用於第二一個分配標誌,這讓我認爲編譯器將使用initializer_list首先創建一個臨時載體,然後使用它的拷貝構造來複制臨時向量爲v2。這是事實嗎?
  • 即使複製列表初始化號,對象會被適當的構造直接構造。對於這種情況,將創建一個臨時std::initializer_list<int>,然後調用std::vector::vector(std::initializer_list<T>, const Allocator& = Allocator())構造v2

    +0

    有趣的是,在C++ 17中,如果使用auto和僅包含一個元素的列表,它可能會有所不同。 – EFenix

    +1

    @AntonioGarrido不,它不會。 'auto v = {1}'永遠不會推導出'std :: vector'。事實上,現在它會推導出'int'而不是'std :: initializer_list',但與關於'std :: vector'的討論完全無關。 – bolov

    +1

    @AntonioGarrido如果您想將C++ 17和auto引入討論,可能會有點相關,您可以編寫'auto v = vector {1,2,3}'(構造函數的模板扣除) – bolov