I recently had an error in my program that surprised me a little, but maybe it shouldn't be, with a lot of initialization types that C ++ provides (especially modern C ++). I have a class that looks something like this:
struct foo
{
foo(const std::set<int> &values) { values_ = values; }
set::set<int> values_;
};
When building foos, it is usually easiest to specify a set of inline values using a list of initializers (an instance usually has 2-3 known values that are known at compile time), for example:
auto f = std::make_shared<foo>({ 1, 2, 3 });
However, I remember that when I first wrote the class foo, the above use gave me compilation problems; I don’t remember the exact error, but I found that an explicit call to the constructor initializer_listallowed the compiler to correctly determine how to process the arguments, for example:
auto f = std::make_shared<foo>(std::initializer_list<int>({ 1, 2, 3 }));
This "worked" for a long time, but recently, my application has had some unclear, random crashes. After debugging, it was found that the change is higher:
auto f = std::make_shared<foo>(std::initializer_list<int>{ 1, 2, 3 });
(i.e., the transition from copy initialization to the copied initializer) fixed the problem. This brings me to the question:
Is copying a list of initializers, as shown in the example above, a dangerous practice? Is the lifetime of the values in the coordinated initializer not the same as the lifetime of a complete closed expression?
, - , ( Apple clang v8.0).