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.

### 2583. There is no way to supply an allocator for `basic_string(str, pos)`

Section: 21.3.3.3 [string.cons] Status: C++17 Submitter: Pablo Halpern Opened: 2016-01-05 Last modified: 2017-07-30

Priority: 0

View all other issues in [string.cons].

View all issues with C++17 status.

Discussion:

Container and `string` constructors in the standard follow two general rules:

1. Every constructor needs a version with and without an allocator argument (possibly through the use of default arguments).

2. Every constructor except the copy constructor for which an allocator is not provided uses a default-constructed allocator.

The first rule ensures emplacing a `string` into a container that uses a scoped allocator will correctly propagate the container's allocator to the new element.

The current standard allows constructing a `string` as `basic_string(str, pos)` but not `basic_string(str, pos, alloc)`. This omission breaks the first rule and causes something like the following to fail:

>     typedef basic_string<char, char_traits<char>, A<char>> stringA;
>     vector<stringA, scoped_allocator_adaptor<A<stringA>>> vs;
>     stringA s;

>     vs.emplace_back(s, 2); // Ill-formed

[2016-02, Issues Telecon]

P0; move to Tentatively Ready.

Proposed resolution:

This wording is relative to N4567.

1. Change 21.3.3 [basic.string], class template `basic_string` synopsis, as indicated

   >     basic_string(const basic_string& str, size_type pos, size_type n = npos,
   >                  const Allocator& a = Allocator());
   >     basic_string(const basic_string& str, size_type pos, size_type n,
   >                  const Allocator& a = Allocator());

2. Change 21.3.3.3 [string.cons] as indicated

   >     basic_string(const basic_string& str,
   >                  size_type pos, size_type n = npos,
   >                  const Allocator& a = Allocator());

   > > -3- Throws: `out_of_range` if `pos > str.size()`.

   > > -4- Effects: Constructs an object of class `basic_string` and determines the effective length `rlen` of the initial string value as the smaller of `n` and `str.size() - pos`, as indicated in Table 65.

   >     basic_string(const basic_string& str, size_type pos, size_type n,
   >                  const Allocator& a = Allocator());

   > > -?- Throws: `out_of_range` if `pos > str.size()`.

   > > -?- Effects: Constructs an object of class `basic_string` and determines the effective length `rlen` of the initial string value as the smaller of `n` and `str.size() - pos`, as indicated in Table 65.

   > > Table 65 — `basic_string(const basic_string&, size_type, size_type, const Allocator&)` and `basic_string(const basic_string&, size_type, size_type, const Allocator&)` effects
   > > Element | Value
   > > --- | ---
   > > `data()` | points at the first element of an allocated copy of `rlen` consecutive elements of the string controlled by `str` beginning at position `pos`
   > > `size()` | `rlen`
   > > `capacity()` | a value at least as large as `size()`