Title
The range constructor makes basic_string_view not trivially move constructible
Status
c++23
Section
[string.view.cons]
Submitter
Jiang An, Casey Carter

Created on 2021-08-16.00:00:00 last changed 13 months ago

Messages

Date: 2021-10-14.09:56:08

Proposed resolution:

This wording is relative to N4892.

  1. Modify [string.view.cons] as indicated:

    template<class R>
      constexpr basic_string_view(R&& r);
    

    -10- Let d be an lvalue of type remove_cvref_t<R>.

    -11- Constraints:

    1. (11.?) — remove_cvref_t<R> is not the same type as basic_string_view,

    2. (11.1) — R models ranges::contiguous_range and ranges::sized_range,

    3. (11.2) — is_same_v<ranges::range_value_t<R>, charT> is true,

    4. […]

Date: 2021-10-14.00:00:00

[ 2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP. ]

Date: 2021-09-15.00:00:00

[ 2021-09-20; Reflector poll ]

Set status to Tentatively Ready after nine votes in favour during reflector poll.

Date: 2021-08-23.13:28:40

Jiang An:

The issue is found in this Microsoft STL pull request.

I think an additional constraint should be added to [string.view.cons]/11 (a similar constraint is already present for reference_wrapper):

(11.?) — is_same_v<remove_cvref_t<R>, basic_string_view> is false.

Casey Carter:

P1989R2 "Range constructor for std::string_view 2: Constrain Harder" added a converting constructor to basic_string_view that accepts (by forwarding reference) any sized contiguous range with a compatible element type. This constructor unfortunately intercepts attempts at move construction which previously would have resulted in a call to the copy constructor. (I suspect the authors of P1989 were under the mistaken impression that basic_string_view had a defaulted move constructor, which would sidestep this issue by being chosen by overload resolution via the "non-template vs. template" tiebreaker.)

The resulting inefficiency could be corrected by adding a defaulted move constructor and move assignment operator to basic_string_view, but it would be awkward to add text to specify that these moves always leave the source intact. Presumably this is why the move operations were omitted in the first place. We therefore recommend constraining the conversion constructor template to reject arguments whose decayed type is basic_string_view (which we should probably do for all conversion constructor templates in the Standard Library).

Implementation experience: MSVC STL is in the process of implementing this fix. Per Jonathan Wakely, libstdc++ has a similar constraint.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2021-10-14 09:56:08adminsetmessages: + msg12138
2021-10-14 09:56:08adminsetstatus: voting -> wp
2021-09-29 12:57:28adminsetstatus: ready -> voting
2021-09-20 11:21:54adminsetmessages: + msg12047
2021-09-20 11:21:54adminsetstatus: new -> ready
2021-08-21 16:26:48adminsetmessages: + msg12014
2021-08-16 00:00:00admincreate