2013-06-05 60 views
2

如果我這樣做:的std :: initializer_list和=操作

MyClass a=b; 

它使用拷貝構造函數初始化a,並且=運算符重載不參與,對不對?

如果a已經初始化,然後我將其分配給其他東西,則將使用=運算符。

我看到this

S(std::initializer_list<T> l) : v(l) { 

使用,如:

S<int> s = {1, 2, 3, 4, 5}; // direct list-initialization 

這很有趣。它是初始化,它使用=運算符,但它調用的不是複製構造函數的構造函數。它爲何不拿,而不是語法是這樣的:

S<int> s {1, 2, 3, 4, 5}; 

那怎麼std::vectorconstructorstd::initializer_list作品。使用=運算符來初始化一個對象,當該運算符沒有調用複製構造時,看起來很混亂,不是嗎?

+0

[測試](http://coliru.stacked-crooked.com/view?id=32e42256c131b9f31d69b59d16ccecbf-50d9cfc8a1d350e7409e81e87c2653ba) –

回答

11

這使用拷貝構造函數來初始化a,並且不涉及=運算符重載,對嗎?

沒錯。

爲什麼它沒有采取像這樣的語法:[...]

您可以使用這兩種形式,它們大多是等價的,除了一個事實,即使用=形式被稱爲複製列表初始化,它需要一個非explicit構造函數(感謝尼科爾布拉斯糾正)。

沒有=形式,在另一方面,被稱爲直接列表初始化和它的作品(相當直觀)從初始直接構建你的對象(通過初始化作爲參數傳遞給的構造函數該對象將被初始化)。無論構造函數是否爲explicit在這裏都不相關。

簡而言之,這兩種形式是等價的,除非複製列表初始化將不起作用,如果您的構造函數是explicit。如果不是這種情況,選擇哪種形式大多是風格問題。

+0

[明確](http://coliru.stacked-crooked.com/view?id=b09efd59be75e347c103c4bde4158689-50d9cfc8a1d350e7409e81e87c2653ba) –

+0

@MarkGarcia:的確如此:) –

+0

我想象,因爲它是通過列表的構造函數,你可以也寫爲第三個選項,如'S s({1,2,3,4,5});' – johnbakers

3

MyClass a=b;只有在b類型爲MyClass時才使用複製構造函數。

如果bOtherClass,就需要另一個構造,這不是拷貝構造函數,只是一個自定義的構造以OtherClass作爲參數(或更可能const OtherClass&,但這是無關的問題 - 只是防止nitpickers :)。

這與initializer_list的示例相同:它是S類型的普通構造函數,它將初始化程序列表作爲參數。從這個意義上說,它與一些假設的構造函數S(int n)沒有區別。

試想一下,如果你有:

S(int n) : v(n) {} // ctor taking an int 

你可以這樣創建一個實例:

S s = 4; 

這同樣適用於初始化列表。

+0

尼斯類似的例子。 –

相關問題