2009-12-08 19 views
12

是否有經驗法則決定何時使用舊的語法()而不是新的語法{}在C++ 0x中統一初始化,何時使用()而不是{}?

要初始化一個結構:在vector例如情況

struct myclass 
{ 
    myclass(int px, int py) : x(px), y(py) {} 
private: 
    int x, y; 
}; 
... 
myclass object{0, 0}; 

現在,它有很多的構造函數。每當我做到以下幾點:

vector<double> numbers{10}; 

我得到元素的矢量,而不是一個與元素作爲一個構造函數是:

explicit vector (size_type n, const T& value= T(), const Allocator& = Allocator()); 

我懷疑的是,每當類定義了一個構造函數,就像在矢量的情況下一樣,它將被調用,語法爲{}

所以,我在想什麼是正確的。即只有當一個類定義了一個初始化列表構造函數來調用不同的構造函數時,我才應該回到舊的語法嗎?例如糾正上面的代碼:

vector<double> numbers(10); // 10 elements instead of just one element with value=10 
+6

這是否意味着在添加初始化程序列表構造函數時可以破壞類客戶端?哎喲。 – 2009-12-08 00:23:00

+2

不,初始化器構造函數不會影響AFAIK中的其他構造函數。 – 2009-12-08 01:22:43

+1

@dribeas:這是確定的。假設你的類最初有一個構造函數,它接受一個int參數,並且你很樂意用新的語法創建實例。如果一個新的構造函數被添加了'initializer_list ',那麼現在所有這些對象都不會使用添加的構造函數嗎?除非網絡上的例子過時,並且聲明一個帶有列表的向量實際上應該看起來像'vector v {{2,1}};'我沒有看到括號會在任何地方出現。 – UncleBens 2009-12-08 14:15:35

回答

2

在此請看:

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=453&rll=1

對一個變量的使用{}風格的初始化中對任何構造沒有直接映射到初始化列表的類。這些構造函數初始化列表可以添加/刪除/修改而不會破壞現有的調用者。

基本上容器的不同行爲是特殊的,並且需要該容器中的特殊代碼,特別是構造函數採取std::initializer_list。對於POD和簡單對象,可以互換使用{}()

+0

「對於POD和簡單對象,可以交替使用{}和()。」不,'()'只在存在構造函數的情況下才起作用,除了複製構造函數外,該構造函數不會使對象成爲POD。另一方面,{}'仍然有效。 – Potatoswatter 2013-08-15 00:42:27

9

我在標準文檔中找到了答案(latest draft)。希望我會試着解釋我的理解。

首先,如果一個類定義了一個初始化列表構造器,那麼它被使用的合適的每當:

§8.5.4(第203頁)

初始化器列表構造器 優於 列表初始化(13.3.1.7)中的其他構造函數。

我覺得這是一個很大的特點有,消除了與不均勻風格:)

反正相關的頭痛,唯一的疑難雜症(其中我的問題是有關)是,如果你設計一個沒有初始化構造函數的類,然後在稍後添加它可能會得到令人驚訝的結果。

基本上,想象std::vector沒有初始化列表構造函數,那麼下面將創建一個向量有10個元素:

std::vector<int> numbers{10}; 

通過添加初始化列表構造函數,編譯器將有利於它比其他由於{}語法的構造函數。這種行爲會發生,因爲init-list {10}的元素是使用init-list構造函數接受的。如果沒有可接受的轉換,則應使用任何其他構造函數,例如:

std::vector<string> vec{10}; 
// a vector of 10 elements. 
// the usual constructor got used because "{0}" 
// is not accepted as an init-list of type string. 
相關問題