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

### 2788. `basic_string` range mutators unintentionally require a default constructible allocator

Section: 21.3.3.7.2 [string.append], 21.3.3.7.3 [string.assign], 21.3.3.7.4 [string.insert], 21.3.3.7.6 [string.replace] Status: C++17 Submitter: Billy O'Neal III Opened: 2016-10-25 Last modified: 2017-07-30

Priority: 2

View all other issues in [string.append].

View all issues with C++17 status.

Discussion:

Email discussion occurred on the lib reflector.

`basic_string`'s mutation functions show construction of temporary `basic_string` instances, without passing an allocator parameter. This says that `basic_string` needs to use a default-initialized allocator, which is clearly unintentional. The temporary needs to use the same allocator the current `basic_string` instance uses, if an implmentation needs to create a temporary at all.

libc++ already does this; I believe libstdc++ does as well (due to the bug report we got from a user that brought this to our attention), but have not verified there. I implemented this in MSVC++'s STL and this change is scheduled to ship in VS "15" RTW.

[2016-11-12, Issaquah]

Sat AM: Priority 2

Alisdair to investigate and (possibly) provide an alternate P/R

[2017-02-13 Alisdair responds:]

Looks good to me - no suggested alternative

[Kona 2017-02-28]

Accepted as Immediate.

Proposed resolution:

This wording is relative to N4606.

1. In 21.3.3.7.2 [string.append], add the allocator parameter to the range overload temporary:

   >     template<class InputIterator>
   >       basic_string& append(InputIterator first, InputIterator last);

   > > -19- Requires: `[first, last)` is a valid range.

   > > -20- Effects: Equivalent to `append(basic_string(first, last, get_allocator()))`.

   > > -21- Returns: `*this`.

2. In 21.3.3.7.3 [string.assign], add the allocator parameter to the range overload temporary:

   >     template<class InputIterator>
   >       basic_string& assign(InputIterator first, InputIterator last);

   > > -23- Effects: Equivalent to `assign(basic_string(first, last, get_allocator()))`.

   > > -24- Returns: `*this`.

3. In 21.3.3.7.4 [string.insert], add the allocator parameter to the range overload temporary:

   >     template<class InputIterator>
   >       iterator insert(const_iterator p, InputIterator first, InputIterator last);

   > > -23- Requires: `p` is a valid iterator on `*this`. `[first, last)` is a valid range.

   > > -24- Effects: Equivalent to `insert(p - begin(), basic_string(first, last, get_allocator()))`.

   > > -25- Returns: An iterator which refers to the copy of the first inserted character, or `p` if `first == last`.

4. In 21.3.3.7.6 [string.replace], add the allocator parameter to the range overload temporary:

   >     template<class InputIterator>
   >       basic_string& replace(const_iterator i1, const_iterator i2,
   >                             InputIterator j1, InputIterator j2);

   > > -32- Requires: `[begin(), i1)`, `[i1, i2)` and `[j1, j2)` are valid ranges.

   > > -33- Effects: Calls `replace(i1 - begin(), i2 - i1, basic_string(j1, j2, get_allocator()))`.

   > > -34- Returns: `*this`.