Title
There is no way to supply an allocator for basic_string(str, pos)
Status
c++17
Section
[string.cons]
Submitter
Pablo Halpern

Created on 2016-01-05.00:00:00 last changed 90 months ago

Messages

Date: 2016-02-07.20:24:45

Proposed resolution:

This wording is relative to N4567.

  1. Change [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 [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()
Date: 2016-02-07.20:24:45

[ 2016-02, Issues Telecon ]

P0; move to Tentatively Ready.

Date: 2016-01-05.00:00:00

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

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2016-03-07 04:11:48adminsetstatus: ready -> wp
2016-02-07 20:24:45adminsetmessages: + msg7972
2016-02-07 20:24:45adminsetstatus: new -> ready
2016-01-16 20:54:50adminsetmessages: + msg7684
2016-01-05 00:00:00admincreate