我最近在初始化列表中遇到了一些問題。考慮一個存儲地圖狀數據的程序從初始化程序列表初始化,但沒有{{{{{{{{...}}}}}}}}?
struct MyMapLike {
MyMapLike(std::map<std::string, int> data)
:data(std::move(data))
{ }
private:
std::map<std::string, int> data;
};
這看起來很直接。但是初始化時,它變得很難看。我想讓它看起來像
MyMapLike maps = { { "One", 1 }, { "Two", 2 } };
但是,編譯器並不想接受這一點,因爲上面意味着它應該尋找一個兩個參數的構造函數,可以分別接受{ "One", 1 }
和{ "Two", 2 }
。我需要添加額外的支架,使它看起來像一個單一參數的構造函數接受{ { ... }, { ... } }
MyMapLike maps = { { { "One", 1 }, { "Two", 2 } } };
我不希望把它寫這樣的。因爲我有一個類似map的類,並且初始化程序具有映射列表的抽象值,所以我想使用前一個版本,並且獨立於任何這樣的實現細節,比如構造函數的嵌套層次。
一個解決辦法是宣佈一個初始化列表構造
struct MyMapLike {
MyMapLike(std::initializer_list<
std::map<std::string, int>::value_type
> vals)
:data(vals.begin(), vals.end())
{ }
MyMapLike(std::map<std::string, int> data)
:data(std::move(data))
{ }
private:
std::map<std::string, int> data;
};
現在我可以用前者,因爲當我有一個初始化列表構造,整個初始化列表作爲一個元素,而不是治療被分解成元素。但我認爲構造函數的這個單獨的需求是醜陋的。
我在尋找指導:
- 你認爲怎麼樣初始化前者和後者的形式?在這種情況下需要額外的支架是否有意義?
- 您是否認爲在這種情況下添加初始化程序列表構造函數的要求很差?
如果你同意我的看法,以前的初始化方式更好,你會想到什麼解決方案?
@MooingDuck,我想他就是這麼做的!請參閱':: value_type'。 – 2013-12-21 20:11:20
「額外」的外部'{}'做與內部不同的東西:它們是大括號初始化語法的一部分,表明構造函數調用正在發生,但是* not *是實際對象的一部分被傳遞給構造函數。同時,內括號表示映射的初始化程序列表的實際開始。我認爲這很有道理,事實上,Clang警告最外面的一系列大括號中的某些(合法的)部分,所以我期望'{{/ * ... stuff ... * /}}'將會變得相當標準他們更喜歡使用大括號初始化語法。 – 2015-12-15 21:34:49