This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Moved to DR at the October, 2012 meeting.]
A question has arisen over expected behavior when an initializer_list is a non-static data member of a class. Initialization of an initializer_list is defined in terms of construction from an implicitly allocated array whose lifetime "is the same as that of the initializer_list object". That would mean that the array needs to live as long as the initializer_list does, which would on the face of it appear to require the array to be stored in something like a std::unique_ptr<T[]> within the same class (if the member is initialized in this manner).
It would be surprising if that was the intent, but it would make initializer_list usable in this context.
It would also be reasonable if this behaved similarly to binding temporaries to reference members (i.e., "temporary bound to a reference member in a constructor's ctor-initializer (11.9.3 [class.base.init]) persists until the constructor exits."), though this approach would probably prevent use of an initializer_list member in that context.
Proposed resolution (February, 2012):
Change 9.4.5 [dcl.init.list] paragraphs 5-6 as follows:
An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated
ana temporary array of N elements of type E, where...
The lifetime of the array is the same as that of the initializer_list object.The array has the same lifetime as any other temporary object (6.7.7 [class.temporary]), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary. [Example:typedef std::complex<double> cmplx; std::vector<cmplx> v1 = { 1, 2, 3 }; void f() { std::vector<cmplx> v2{ 1, 2, 3 }; std::initializer_list<int> i3 = { 1, 2, 3 }; } struct A { std::initializer_list<int> i4; A(): i4{1,2,3} { } // creates an A with a dangling reference };For v1 and v2, the initializer_list object is a parameter in a function call, so the
andarray created for { 1, 2, 3 }havehas full-expression lifetime. For i3, the initializer_list object is a variable, so theandarrayhave automaticpersists for the lifetime of the variable. For i4, the initializer_list object is initialized in a constructor's ctor-initializer, so the array persists only until the constructor exits, and so any use of the elements of i4 after the constructor exits produces undefined behavior. —end example] [Note: The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. —end note]
Change 6.7.7 [class.temporary] paragraph 5 as follows:
The second context is when a reference is bound to a temporary. [Footnote: The same rules apply to initialization of an initializer_list object (9.4.5 [dcl.init.list]) with its underlying temporary array. —end footnote] The temporary to which...