最近我的程序中出現了一個bug,這讓我感到吃驚,但也許它不應該,C++(特別是現代C++)提供了大量的初始化類型。我有一個類,它看起來是這樣的:這是一個支撐初始化列表的不安全用法?
struct foo
{
foo(const std::set<int> &values) { values_ = values; }
set::set<int> values_;
};
在構建foo
S,它通常是最容易指定一組內嵌使用初始化列表值(一個實例通常會有2-3個已知值已知在編譯時),就像這樣:
auto f = std::make_shared<foo>({ 1, 2, 3 });
不過,我記得,當我第一次寫作課foo
,上述用法給我的編譯時間問題;我不記得確切的錯誤,但我發現,明確調用initializer_list
構造允許編譯器正確推斷如何處理這些參數,就像這樣:
auto f = std::make_shared<foo>(std::initializer_list<int>({ 1, 2, 3 }));
這種「工作」很長一段時間,但我的應用程序最近遇到了一些模糊不清的隨機崩潰。調試後,我們發現,改變上述給:
auto f = std::make_shared<foo>(std::initializer_list<int>{ 1, 2, 3 });
(即,從副本初始化改變到支撐初始化)固定的問題。這使我想到這個問題:
上面的示例中顯示的初始化程序列表的複製構造是不安全的做法嗎?支撐初始值設定項中值的生存期是否與全封閉表達式的生命週期不匹配?
這可能只是一些其他的,仍然存在的錯誤的症狀,或某種編譯器錯誤(我正在使用Apple clang v8.0)。
請顯示您的構造函數定義。 –
@KerrekSB:已添加。我所做的只是複製作爲參數傳入的'set'。這是一個非常簡化的版本;啓發'foo'的實際班級要複雜得多。但是,在'set'上完成的唯一操作如示例中所示。 –
您遇到的錯誤與此處的初始化無關。通過一些動態消毒劑(Valgrind,ASAN,TSAN)運行你的程序來找到真正的錯誤。 –