initializer_list
constructor requirementsSection: 23.2.4 [sequence.reqmts], 23.2.7 [associative.reqmts], 23.2.8 [unord.req], 29.5.3.2 [rand.req.seedseq] Status: Open Submitter: Jeffrey Yasskin Opened: 2012-10-21 Last modified: 2020-09-06
Priority: 3
View other active issues in [sequence.reqmts].
View all other issues in [sequence.reqmts].
View all issues with Open status.
Discussion:
In 23.2.4 [sequence.reqmts] p3, we have "il
designates an object of type
initializer_list<value_type>
", and then several functions that take
'il
' as an argument. However, an expression like {1, 2, 'a'}
is not
an object of type initializer_list<int>
unless it's used to initialize
an explicitly-typed variable of that type. I believe we want:
std::vector<int> v; v = {1, 2, 'a'};
to compile portably, so we should say something different when defining 'il
'. The
same phrasing happens in 23.2.7 [associative.reqmts], 23.2.8 [unord.req], and
29.5.3.2 [rand.req.seedseq].
initializer_list<exact_type>
.
[2013-03-15 Issues Teleconference]
Moved to Open.
This is definitely not NAD
Should copy the suggested wording as the proposed resolution.
[2019-03-26; Daniel comments and provides wording]
The 2013-03-15 comment is confusing, since it recommends to "copy the suggested wording as the proposed resolution".
I couldn't find such wording in the issue nor in the associated wiki, so I provided that wording out of myself.
The tricky part is to define which kind of braced-init-list we want to allow. As Tim Song pointed out, we
still need the existing support for std::initializer_list<value_type>
as well, because otherwise
existing semantics based on expressions such as li.begin()
won't work anymore.
The below suggested wording restricts supported braced-init-lists to every initializer list that can be used
to copy-list-initialize an object of type std::initializer_list<value_type>
by saying:
"
bil
designates any braced-init-list suitable to copy-list-initialize an object of typeinitializer_list<value_type>
(9.4.5 [dcl.init.list])"
As a drive-by fix, the provided wording adds another initialization "expression" that makes the construction of the form
std::vector<int> v = {1, 2, 'a'};
valid (We just miss a copy-initialization case).
Proposed resolution:
This wording is relative to N4810.
[Drafting note: We need to special-case the "expression"
X u = bil;
below, because for empty braced-init-list the effects are those of calling the default constructor. — end drafting note]
Modify 23.2.4 [sequence.reqmts] as indicated:
-3- In Tables 66 and 67, […]
il
designates an objectvalue of typeinitializer_list<value_type>
,bil
designates any braced-init-list suitable to copy-list-initialize an object of typeinitializer_list<value_type>
(9.4.5 [dcl.init.list]), […]
Modify Table 66 — "Sequence container requirements (in addition to container)" as indicated:
Table 66 — Sequence container requirements (in addition to container) Expression Return type Assertion/note
pre-/post-condition[…]
X(il)
X u = il;
Equivalent to X(il.begin(), il.end())
orX u(il.begin(), il.end());
, respectivelyX(bil)
Equivalent to X(initializer_list<value_type>(bil))
X u = bil;
If bil
is empty, equivalent toX u;
, otherwise
equivalent toX u = initializer_list<value_type>(bil);
a = il
X&
[…] a = bil
X&
Equivalent to a = initializer_list<value_type>(bil)
[…]
a.insert(p, il)
iterator
[…] a.insert(p, bil)
iterator
Equivalent to a.insert(p, initializer_list<value_type>(bil))
[…]
a.assign(il)
void
[…] a.assign(bil)
void
Equivalent to a.assign(initializer_list<value_type>(bil))
[…]
Modify 23.2.7 [associative.reqmts] as indicated:
-8- In Table 69, […]
il
designates an objectvalue of typeinitializer_list<value_type>
,bil
designates any braced-init-list suitable to copy-list-initialize an object of typeinitializer_list<value_type>
(9.4.5 [dcl.init.list]), […]
Modify Table 69 — "Associative container requirements (in addition to container)" as indicated:
Table 69 — Associative container requirements (in addition to container) Expression Return type Assertion/note
pre-/post-conditionComplexity […]
X(il)
X u = il;
same as X(il.begin(), il.end())
orX u(il.begin(), il.end());
, respectivelysame as X(il.begin(), il.end())
orX u(il.begin(), il.end());
, respectivelyX(bil)
Equivalent to X(initializer_list<value_type>(bil))
X u = bil;
If bil
is empty, equivalent toX u;
, otherwise
equivalent toX u = initializer_list<value_type>(bil);
X(il,c)
same as X(il.begin(), il.end(), c)
same as X(il.begin(), il.end(), c)
X(bil, c)
Equivalent to X(initializer_list<value_type>(bil), c)
a = il
X&
[…] […] a = bil
X&
Equivalent to a = initializer_list<value_type>(bil)
[…]
a.insert(il)
void
equivalent to a.insert(il.begin(), il.end())
a.insert(bil)
void
Equivalent to a.insert(initializer_list<value_type>(bil))
[…]
a.assign(il)
void
[…] a.assign(bil)
void
Equivalent to a.assign(initializer_list<value_type>(bil))
[…]
Modify 23.2.8 [unord.req] p11's bullet list as indicated:
-11- In Table 70:
(11.1) — […]
[…]
(11.14) —
il
denotes a value of typeinitializer_list<value_type>
,(11.?) —
bil
denotes any braced-init-list suitable to copy-list-initialize an object of typeinitializer_list<value_type>
(9.4.5 [dcl.init.list]),[…]
Modify Table 70 — "Unordered associative container requirements (in addition to container)" as indicated:
[Drafting note: There is a preexisting issue with Table 70, that there is no symbol
u
specified ("u
denotes the name of a variable being declared"), so existing initialization forms with a named variable are currently always written as "X a[…]
" wherea
is defined as "a
denotes a value of typeX
", the wording below follows this existing practice but the author of this wording would like to kindly ask the Project Editor to introduce said symbolu
and apply it to all existing and new such named initialization forms instead. — end drafting note]
Table 70 — Unordered associative container requirements (in addition to container) Expression Return type Assertion/note
pre-/post-conditionComplexity […]
X(il)
X a = il;
X
Same as X(il.begin(), il.end())
orX a(il.begin(), il.end());
, respectivelySame as X(il.begin(), il.end())
orX a(il.begin(), il.end());
, respectivelyX(bil)
X
Equivalent to X(initializer_list<value_type>(bil))
X a = bil;
X
If bil
is empty, equivalent toX a;
, otherwise
equivalent toX a = initializer_list<value_type>(bil);
X(il, n)
X
Same as X(il.begin(), il.end(), n)
Same as X(il.begin(), il.end(), n)
X(bil, n)
X
Equivalent to X(initializer_list<value_type>(bil), n)
X(il, n, hf)
X
Same as X(il.begin(), il.end(), n, hf)
Same as X(il.begin(), il.end(), n, hf)
X(bil, n, hf)
X
Equivalent to X(initializer_list<value_type>(bil), n, hf)
X(il, n, hf, eq)
X
Same as X(il.begin(), il.end(), n, hf, eq)
Same as X(il.begin(), il.end(), n, hf, eq)
X(bil, n, hf, eq)
X
Equivalent to X(initializer_list<value_type>(bil), n, hf, eq)
[…]
a = il
X&
[…] […] a = bil
X&
Equivalent to a = initializer_list<value_type>(bil)
[…]
a.insert(il)
void
Same as a.insert(il.begin(), il.end())
.Same as a.insert(il.begin(), il.end())
.a.insert(bil)
void
Equivalent to a.insert(initializer_list<value_type>(bil))
[…]
Modify 29.5.3.2 [rand.req.seedseq] p2's bullet list as indicated:
-2- A class
S
satisfies the requirements of a seed sequence if the expressions shown in Table 82 are valid and have the indicated semantics, and […] In that Table and throughout this subclause:
(2.1) — […]
(2.?) —
u
denotes the name of a variable being declared,[…]
(2.6) —
il
is a value ofinitializer_list<T>
.;(2.?) —
bil
denotes any braced-init-list suitable to copy-list-initialize an object of typeinitializer_list<T>
(9.4.5 [dcl.init.list]).
Modify Table 82 — "Seed sequence requirements" as indicated:
Table 82 — Seed sequence requirements Expression Return type Pre/post-condition Complexity […]
S(il)
S u = il;
Same as S(il.begin(), il.end())
orS u(il.begin(), il.end());
, respectivelysame as S(il.begin(), il.end())
orS u(il.begin(), il.end());
, respectivelyS(bil)
Equivalent to S(initializer_list<T>(bil))
S u = bil;
If bil
is empty, equivalent toS u;
, otherwise
equivalent toS u = initializer_list<T>(bil);
[…]