LWG 2758 corrected newly introduced ambiguities of std::string::assign and other functions
that got new overloads taking a basic_string_view as argument, but the assignment operator of
basic_string and other functions taking a parameter of type basic_string_view<charT, traits>
were not corrected. Similar to the previous issue the following operations lead now to an ambiguity as well:

The right fix is to convert all member functions taken a basic_string_view<charT, traits> parameter
into constrained function templates.

When doing so, it turns out that there occurs an additional problem: The functions that had been massaged by LWG
2758 are all functions that are not specified to be noexcept, but the wider range of
"string operation" functions taking a basic_string_view<charT, traits> parameter are mostly
noexcept because they had a wide contract. Now with the approach of LWG 2758, there are all
types allowed that are convertible to basic_string_view<charT, traits>, but the conversion
occurs now in the function body, not outside of it. So, if these conversion would be potentially
exception-throwing, this would lead to a call to std::terminate, which is a semantic change compared to
the previous specification. There are several options to handle this situation:

Ignore that and let std::terminate come into action. This is a different way of saying that
we impose the requirement of a nothrowing operation.

Remove noexcept from all the affected functions.

Make these functions conditionally noexcept.

The submitter has a personal preference for option (3), except that this would complicate the wording a bit,
because unfortunately there exists yet no trait std::is_nothrow_convertible (See LWG 2040).
A seemingly low-hanging fruit would be the attempt to use std::is_nothrow_constructible instead, but this
trait describes a potentially different initialization context and is therefore inappropriate. Option (1) would
conserve the existing noexcept guarantee for all non-throwing conversions, but now these functions become
narrow-contract functions and at least according to the current noexcept
guidelines such functions should not be marked as noexcept. But there are exceptions possible
for that rule, and the initially suggested proposed wording below argues that this exception is reasonable here,
because the required wording fixes just an unintended side-effects of transforming the functions into functions
templates, but it doesn't intend to change the actual functionality.

Some of the below suggested overload exclusion constraints technically don't require the additional
is_convertible_v<const T&, const charT*> == false requirement, but the submitter of this issue
suggests a more advanced approach that should be applied in a synchronous wording adjustment combined with the
existing LWG 2758 wording: It would presumably life easier for implementations (which are allowed
to provide additional member function overloads as conforming extensions), when we would define a mini requirement
set for template parameter type T below:

is_convertible_v<const T&, basic_string_view<charT, traits>> is true.

is_convertible_v<const T&, const charT*> is false.

The implicit conversion to basic_string_view<charT, traits> shall not throw an exception.

But the corresponding slightly revised wording taking advantage of this "concept-like" requirements set will not be
suggested before the upcoming working draft has been published to allow a simpler coordinated adjustment together with
the LWG 2758 wording.

It should also be noted that these changes have impact on deduction behaviour and therefore may require further
adjustments of the deduction rules.

[2017-07-13, Toronto]

LWG preferred to remove in all functions with added nothrow constraints the noexcept specifier (and the
constraint) and to possibly improve the situation later.

-?- Requires: The initialization of sv, as specified below, shall not throw an exception.

-1- Effects:Creates a variable, sv, as if by basic_string_view<charT, traits> sv = t;
and then dDetermines the effective length rlen of the strings to compare as the smaller of
size() and sv.size(). The function then compares the two strings by calling traits::compare(data(),
sv.data(), rlen).

-2- Returns: The nonzero result if the result of the comparison is nonzero. Otherwise, returns a value as
indicated in Table 63.
[…]

To balance the loss of information about the removed noexcept specifications, all affected functions
should get a new Throws: element saying that they won't throw unless this is caused by the conversion to
the local basic_string_view object. The existing P/R has been updated to reflect that suggestion.

[2017-07 Toronto Wed Issue Prioritization]

Priority ; Marshall to investigate and if OK, will propose Tentatively Ready on reflector.

-1- Effects:Creates a variable, sv, as if by basic_string_view<charT, traits> sv = t;
and then dDetermines the effective length rlen of the strings to compare as the smaller of
size() and sv.size(). The function then compares the two strings by calling traits::compare(data(),
sv.data(), rlen).

-2- Returns: The nonzero result if the result of the comparison is nonzero. Otherwise, returns a value as
indicated in Table 63.
[…]

(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".]

-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 (26.2.1 [container.requirements.general]).