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

### 3075. `basic_string` needs deduction guides from `basic_string_view`

Section: 23.4.3 [basic.string], 23.4.3.3 [string.cons] Status: C++20 Submitter: Stephan T. Lavavej Opened: 2018-03-03 Last modified: 2021-02-25

Priority: Not Prioritized

View other active issues in [basic.string].

View all other issues in [basic.string].

View all issues with C++20 status.

Discussion:

The Proposed Resolution for LWG 2946 appears to be correct and we've implemented it in MSVC, but it worsens a pre-existing problem with basic_string class template argument deduction.

The following `s1` and `s2` compiled in C++17 before LWG 2946's PR, fail to compile after LWG 2946's PR, and are fixed by my PR:

>     basic_string s1("cat"sv);
>     basic_string s2("cat"sv, alloc);

The following s4 failed to compile in C++17, and is fixed by my PR:

>     // basic_string s3("cat"sv, 1, 1);
>     basic_string s4("cat"sv, 1, 1, alloc);

(s3 failed to compile in C++17, and would be fixed by my PR, but it is affected by a pre-existing and unrelated ambiguity which I am not attempting to fix here.)

As C++17 and LWG 2946's PR introduced templated constructors for `basic_string` from `basic_string_view`, we need to add corresponding deduction guides.

The constructors take `const T&` that's convertible to `basic_string_view` (the additional constraint about not converting to `const charT*` is irrelevant here). However, CTAD can't deduce `charT` and `traits` from arbitrary user-defined types, so the deduction guides need `T` to be exactly `basic_string_view`.

Additionally, we need to handle the `size_type` parameters in the same way that the unordered containers do. This PR has been implemented in MSVC.

[2018-14: Wednesday night issues processing: both this and 2946 to status "Immediate".]

[2018-3-17 Adopted in Jacksonville]

Proposed resolution:

This wording is relative to N4727.

1. Edit 23.4.3 [basic.string], class template `basic_string` synopsis, as indicated:

   > >     […]

   > >     template<class InputIterator,
   > >              class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
   > >       basic_string(InputIterator, InputIterator, Allocator = Allocator())
   > >         -> basic_string<typename iterator_traits<InputIterator>::value_type,
   > >                         char_traits<typename iterator_traits<InputIterator>::value_type>,
   > >                          Allocator>;

   > >     template<class charT,
   > >              class traits,
   > >              class Allocator = allocator<charT>>
   > >       explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
   > >         -> basic_string<charT, traits, Allocator>;

   > >     template<class charT,
   > >              class traits,
   > >              class Allocator = allocator<charT>>
   > >       basic_string(basic_string_view<charT, traits>, typename see below::size_type, typename see below::size_type,
   > >                    const Allocator& = Allocator())
   > >         -> basic_string<charT, traits, Allocator>;

   > >     }

   > -?- A `size_type` parameter type in a `basic_string` deduction guide refers to the `size_type` member type of the type deduced by the deduction guide.

2. Edit 23.4.3.3 [string.cons] as indicated:

   >     template<class InputIterator,
   >              class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
   >       basic_string(InputIterator, InputIterator, Allocator = Allocator())
   >         -> basic_string<typename iterator_traits<InputIterator>::value_type,
   >                         char_traits<typename iterator_traits<InputIterator>::value_type>,
   >                          Allocator>;

   > > -25- Remarks: Shall not participate in overload resolution if `InputIterator` is a type that does not qualify as an input iterator, or if `Allocator` is a type that does not qualify as an allocator (24.2.2.1 [container.requirements.general]).

   >     template<class charT,
   >              class traits,
   >              class Allocator = allocator<charT>>
   >       explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
   >         -> basic_string<charT, traits, Allocator>;

   >     template<class charT,
   >              class traits,
   >              class Allocator = allocator<charT>>
   >       basic_string(basic_string_view<charT, traits>, typename see below::size_type, typename see below::size_type,
   >                    const Allocator& = Allocator())
   >         -> basic_string<charT, traits, Allocator>;

   > > -?- Remarks: Shall not participate in overload resolution if `Allocator` is a type that does not qualify as an allocator (24.2.2.1 [container.requirements.general]).