在C++標準,§13.3.1.7[over.match.list],以下陳述:如果copy-list-initialization允許顯式構造函數,會出現什麼問題?
在copy-列表初始化,如果選擇一個
explicit
構造,是形成不良的初始化。
這就是爲什麼我們不能做,例如其原因,是這樣的:
struct foo {
// explicit because it can be called with one argument
explicit foo(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
f({ "answer", 42 });
(注意,這裏發生的事情是不是轉換,並且它不會是一個即使構造是「隱」,這是直接使用其構造一個foo
對象的初始化。除了std::string
,沒有轉換這裏。)
這個S eems對我來說非常好。沒有辦法隱式轉換會咬我。
如果{ "answer", 42 }
可以初始化別的東西,編譯器不會背叛我,做錯事:
struct bar {
// explicit because it can be called with one argument
explicit bar(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
void f(bar x);
f({ "answer", 42 }); // error: ambiguous call
沒有任何問題:電話是模糊的,代碼將無法編譯,我必須明確地選擇超載。
f(bar { "answer", 42 }); // ok
由於禁止條款明確規定,我有這種感覺,我在這裏失去了一些東西。據我所見,列表初始化選擇顯式構造函數對我來說似乎不是一個問題:通過使用列表初始化語法,程序員已經表達了做某種「轉換」的願望。
什麼可能出錯?我錯過了什麼?
我不確定,但我認爲這很邏輯。調用f({「answer」,42}),你可能永遠不會知道你傳遞了一個foo,並且你試圖使用的構造函數是明確的,它強制顯式轉換。 – Geoffroy 2012-02-06 07:55:46
@Geoffroy:如果別的東西可以從'{「answer」,42}'傳遞,重載決議將是不明確的,因此迫使我明確類型。 – 2012-02-06 07:58:30
'通過使用列表初始化語法,程序員已經表達了進行某種轉換的願望:但不是爲了foo。如果'f()'有另一個接受初始化列表的重載,該怎麼辦? – sehe 2012-02-06 07:59:31