2742. Inconsistent string interface taking string_view

Section: 27.4.3.3 [string.cons] Status: C++17 Submitter: Richard Smith Opened: 2016-07-06 Last modified: 2020-09-06

Priority: 1

View all other issues in [string.cons].

View all issues with C++17 status.

Discussion:

Generally, basic_string has a constructor matching each assign function and vice versa (except the constructor takes an allocator where assign does not). P0254R2 violates this by adding an assign(basic_string_view, size_type pos, size_type n = npos) but no corresponding constructor.

[2016-08-04 Chicago LWG]

Robert Douglas provides initial wording.

We decided against another constructor overload to avoid the semantic confusion between:

basic_string(char const*, size_type length, Allocator = Allocator())

and

template<class T, class Foo = is_convertible_v<T const&, basic_string_view<charT, traits>>
basic_string(T const&, size_type pos, Allocator = Allocator())

where someone might call:

basic_string("HelloWorld", 5, 5);

and get "World", but then call

basic_string("HelloWorld", 5);

and instead get "Hello". The second parameter changes between length and position.

[08-2016, Chicago]

Fri PM: Move to Tentatively Ready

Proposed resolution:

This wording is relative to N4606.

  1. In 27.4.3 [basic.string] add the following constructor overload:

    […]
    basic_string(const basic_string& str, size_type pos,
                 const Allocator& a = Allocator());
    basic_string(const basic_string& str, size_type pos, size_type n,
                 const Allocator& a = Allocator());
    template<class T>
    basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
    explicit basic_string(basic_string_view<charT, traits> sv,
                          const Allocator& a = Allocator());
    […]
    
  2. In 27.4.3.3 [string.cons] add the following ctor definition:

    template<class T>
    basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
    

    -?- Effects: Creates a variable, sv, as if by basic_string_view<charT, traits> sv = t; and then behaves the same as:

    basic_string(sv.substr(pos, n), a)
    

    -?- Remarks: This constructor shall not participate in overload resolution unless is_convertible_v<const T&, basic_string_view<charT, traits>> is true.