This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Open status.

### 2206. Inaccuracy in `initializer_list` constructor requirements

Section: 24.2.4 [sequence.reqmts], 24.2.7 [associative.reqmts], 24.2.8 [unord.req], 28.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 24.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 24.2.7 [associative.reqmts], 24.2.8 [unord.req], and 28.5.3.2 [rand.req.seedseq].

This may just be an editorial issue because the actual class synopses declare the functions to take `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 type `initializer_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]

1. Modify 24.2.4 [sequence.reqmts] as indicated:

   > -3- In Tables 66 and 67, […] `il` designates an object value of type `initializer_list<value_type>`, `bil` designates any braced-init-list suitable to copy-list-initialize an object of type `initializer_list<value_type>` (9.4.5 [dcl.init.list]), […]

2. 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())` or `X u(il.begin(), il.end());`, respectively
   > `X(bil)` | `` | Equivalent to `X(initializer_list<value_type>(bil))`
   > `X u = bil;` | `` | If `bil` is empty, equivalent to `X u;`, otherwise equivalent to `X 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))`
   > `[…]`

3. Modify 24.2.7 [associative.reqmts] as indicated:

   > -8- In Table 69, […] `il` designates an object value of type `initializer_list<value_type>`, `bil` designates any braced-init-list suitable to copy-list-initialize an object of type `initializer_list<value_type>` (9.4.5 [dcl.init.list]), […]

4. 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-condition | Complexity
   > --- | --- | --- | ---
   > `[…]`
   > `X(il)` `X u = il;` | `` | same as `X(il.begin(), il.end())` or `X u(il.begin(), il.end());`, respectively | same as `X(il.begin(), il.end())` or `X u(il.begin(), il.end());`, respectively
   > `X(bil)` | `` | Equivalent to `X(initializer_list<value_type>(bil))` |
   > `X u = bil;` | `` | If `bil` is empty, equivalent to `X u;`, otherwise equivalent to `X 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))`
   > `[…]`

5. Modify 24.2.8 [unord.req] p11's bullet list as indicated:

   > -11- In Table 70:

   > 1. (11.1) — […]

   > 2. […]

   > 3. (11.14) — `il` denotes a value of type `initializer_list<value_type>`,

   > 4. (11.?) — `bil` denotes any braced-init-list suitable to copy-list-initialize an object of type `initializer_list<value_type>` (9.4.5 [dcl.init.list]),

   > 5. […]

6. 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[…]`" where `a` is defined as "`a` denotes a value of type `X`", the wording below follows this existing practice but the author of this wording would like to kindly ask the Project Editor to introduce said symbol `u` 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-condition | Complexity
   > --- | --- | --- | ---
   > `[…]`
   > `X(il)` `X a = il;` | `X` | Same as `X(il.begin(), il.end())` or `X a(il.begin(), il.end());`, respectively | Same as `X(il.begin(), il.end())` or `X a(il.begin(), il.end());`, respectively
   > `X(bil)` | `X` | Equivalent to `X(initializer_list<value_type>(bil))` |
   > `X a = bil;` | `X` | If `bil` is empty, equivalent to `X a;`, otherwise equivalent to `X 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))` |
   > `[…]`

7. Modify 28.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:

   > 1. (2.1) — […]

   > 2. (2.?) — `u` denotes the name of a variable being declared,

   > 3. […]

   > 4. (2.6) — `il` is a value of `initializer_list<T>`.;

   > 5. (2.?) — `bil` denotes any braced-init-list suitable to copy-list-initialize an object of type `initializer_list<T>` (9.4.5 [dcl.init.list]).

8. 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())` or `S u(il.begin(), il.end());`, respectively | same as `S(il.begin(), il.end())` or `S u(il.begin(), il.end());`, respectively
   > `S(bil)` |  | Equivalent to `S(initializer_list<T>(bil))` |
   > `S u = bil;` |  | If `bil` is empty, equivalent to `S u;`, otherwise equivalent to `S u = initializer_list<T>(bil);` |
   > `[…]`