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.
Section: 27.4.3.3 [string.cons], 27.4.3.7.2 [string.append], 27.4.3.7.3 [string.assign], 27.4.3.8 [string.ops] Status: C++20 Submitter: Daniel Krügler Opened: 2017-03-17 Last modified: 2021-02-25
Priority: 2
View all other issues in [string.cons].
View all issues with C++20 status.
Discussion:
LWG 2758(i) 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:
#include <string> int main() { std::string s({"abc", 1}); s = {"abc", 1}; s += {"abc", 1}; s.append({"abc", 1}); s.assign({"abc", 1}); s.insert(0, {"abc", 1}); s.replace(0, 1, {"abc", 1}); s.replace(s.cbegin(), s.cbegin(), {"abc", 1}); s.find({"abc", 1}); s.rfind({"abc", 1}); s.find_first_of({"abc", 1}); s.find_last_of({"abc", 1}); s.find_first_not_of({"abc", 1}); s.find_last_not_of({"abc", 1}); s.compare({"abc", 1}); s.compare(0, 1, {"abc", 1}); }
The right fix is to convert all member functions taken a basic_string_view<charT, traits>
parameter
into constrained function templates.
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(i), 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(i)).
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.
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(i) 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(i) 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.
Previous resolution [SUPERSEDED]:
This wording is relative to N4640.
Edit 27.4.3 [basic.string], class template
basic_string
synopsis, as indicated:[…] // 21.3.2.2, construct/copy/destroy […] template<class T> explicit basic_string(basic_string_view<charT, traits> svconst T& t, const Allocator& a = Allocator()); […] template<class T> basic_string& operator=(basic_string_view<charT, traits> svconst T& t); basic_string& operator=(const charT* s); […] // 21.3.2.6, modifiers […] template<class T> basic_string& operator+=(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& append(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& assign(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& insert(size_type pos,basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& replace(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& replace(const_iterator i1, const_iterator i2,basic_string_view<charT, traits> svconst T& t); […] // 21.3.2.7, string operations […] template<class T> size_type find (basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept; […] template<class T> size_type rfind(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept; […] template<class T> size_type find_first_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept; […] template<class T> size_type find_last_of (basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept; […] template<class T> size_type find_first_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept; […] template<class T> size_type find_last_not_of (basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept; […] template<class T> int compare(basic_string_view<charT, traits> svconst T& t) const noexcept; […] template<class T> int compare(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t) const; […]Edit 27.4.3.3 [string.cons] as indicated:
template<class T> explicit basic_string(basic_string_view<charT, traits> svconst T& t, const Allocator& a = Allocator());-9- Effects:
-?- Remarks: This constructor shall not participate in overload resolution unlessSame asCreates a variable,basic_string(sv.data(), sv.size(), a)
.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then behaves the same asbasic_string(sv.data(), sv.size(), a)
.is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.[…]
template<class T> basic_string& operator=(basic_string_view<charT, traits> svconst T& t);-25- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return assign(sv); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.op+=] as indicated:
template<class T> basic_string& operator+=(basic_string_view<charT, traits> svconst T& t);-3- Effects: Creates a variable,
-4- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then cCallsappend(sv)
.*this
. -?- Remarks: This function shall not participate in overload resolution unlessis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.7.2 [string.append] as indicated:
template<class T> basic_string& append(basic_string_view<charT, traits> svconst T& t);-6- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return append(sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.7.3 [string.assign] as indicated:
template<class T> basic_string& assign(basic_string_view<charT, traits> svconst T& t);-8- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return assign(sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.7.4 [string.insert] as indicated:
template<class T> basic_string& insert(size_type pos,basic_string_view<charT, traits> svconst T& t);-5- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return insert(pos, sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.7.6 [string.replace] as indicated:
template<class T> basic_string& replace(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t);-5- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return replace(pos1, n1, sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.[…]
template<class T> basic_string& replace(const_iterator i1, const_iterator i2,basic_string_view<charT, traits> svconst T& t);-21- Requires:
-22- Effects: Creates a variable,[begin(), i1)
and[i1, i2)
are valid ranges.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then cCallsreplace(i1 - begin(), i2 - i1, sv)
. -23- Returns:*this
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.8.2 [string.find] as indicated:
template<class T> size_type find(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.rfind] as indicated:
template<class T> size_type rfind(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.find.first.of] as indicated:
template<class T> size_type find_first_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.find.last.of] as indicated:
template<class T> size_type find_last_of(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.find.first.not.of] as indicated:
template<class T> size_type find_first_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit [string.find.last.not.of] as indicated:
template<class T> size_type find_last_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […] -2- Returns:xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.Edit 27.4.3.8.4 [string.compare] as indicated:
template<class T> int compare(basic_string_view<charT, traits> svconst T& t) const noexcept;-?- Requires: The initialization of
-1- Effects: Creates a variable,sv
, as specified below, shall not throw an exception.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the effective lengthrlen
of the strings to compare as the smaller ofsize()
andsv.size()
. The function then compares the two strings by callingtraits::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. […]-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.template<class T> int compare(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t) const;-3- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return basic_string_view<charT, traits>(data(), size()).substr(pos1, n1).compare(sv); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
[2017-07-14, Toronto, Daniel refines wording]
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.
[2018-03-03: STL reported a related issue, LWG 3075(i).]
[2018-14: Wednesday night issues processing: both this and 3075(i) to status "Immediate".]
[2018-3-17 Adopted in Jacksonville]
Proposed resolution:
This wording is relative to N4656.
Edit 27.4.3 [basic.string], class template basic_string
synopsis, as indicated:
[…] // 21.3.2.2, construct/copy/destroy […] template<class T> explicit basic_string(basic_string_view<charT, traits> svconst T& t, const Allocator& a = Allocator()); […] template<class T> basic_string& operator=(basic_string_view<charT, traits> svconst T& t); basic_string& operator=(const charT* s); […] // 21.3.2.6, modifiers […] template<class T> basic_string& operator+=(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& append(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& assign(basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& insert(size_type pos,basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& replace(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t); […] template<class T> basic_string& replace(const_iterator i1, const_iterator i2,basic_string_view<charT, traits> svconst T& t); […] // 21.3.2.7, string operations […] template<class T> size_type find (basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept; […] template<class T> size_type rfind(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept; […] template<class T> size_type find_first_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept; […] template<class T> size_type find_last_of (basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept; […] template<class T> size_type find_first_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept; […] template<class T> size_type find_last_not_of (basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept; […] template<class T> int compare(basic_string_view<charT, traits> svconst T& t) constnoexcept; […] template<class T> int compare(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t) const; […]
Edit 27.4.3.3 [string.cons] as indicated:
template<class T> explicit basic_string(basic_string_view<charT, traits> svconst T& t, const Allocator& a = Allocator());-9- Effects:
-?- Remarks: This constructor shall not participate in overload resolution unlessSame asCreates a variable,basic_string(sv.data(), sv.size(), a)
.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then behaves the same asbasic_string(sv.data(), sv.size(), a)
.is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.[…]
template<class T> basic_string& operator=(basic_string_view<charT, traits> svconst T& t);-25- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return assign(sv); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit [string.op+=] as indicated:
template<class T> basic_string& operator+=(basic_string_view<charT, traits> svconst T& t);-3- Effects: Creates a variable,
-4- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then cCallsappend(sv)
.*this
. -?- Remarks: This function shall not participate in overload resolution unlessis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit 27.4.3.7.2 [string.append] as indicated:
template<class T> basic_string& append(basic_string_view<charT, traits> svconst T& t);-6- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return append(sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit 27.4.3.7.3 [string.assign] as indicated:
template<class T> basic_string& assign(basic_string_view<charT, traits> svconst T& t);-8- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return assign(sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit 27.4.3.7.4 [string.insert] as indicated:
template<class T> basic_string& insert(size_type pos,basic_string_view<charT, traits> svconst T& t);-5- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return insert(pos, sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit 27.4.3.7.6 [string.replace] as indicated:
template<class T> basic_string& replace(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t);-5- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return replace(pos1, n1, sv.data(), sv.size()); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.[…]
template<class T> basic_string& replace(const_iterator i1, const_iterator i2,basic_string_view<charT, traits> svconst T& t);-21- Requires:
-22- Effects: Creates a variable,[begin(), i1)
and[i1, i2)
are valid ranges.sv
, as if bybasic_string_view<charT, traits> sv = t;
and then cCallsreplace(i1 - begin(), i2 - i1, sv)
. -23- Returns:*this
.-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.
Edit 27.4.3.8.2 [string.find] as indicated:
template<class T> size_type find(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit [string.rfind] as indicated:
template<class T> size_type rfind(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit [string.find.first.of] as indicated:
template<class T> size_type find_first_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit [string.find.last.of] as indicated:
template<class T> size_type find_last_of(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit [string.find.first.not.of] as indicated:
template<class T> size_type find_first_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = 0) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the lowest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit [string.find.last.not.of] as indicated:
template<class T> size_type find_last_not_of(basic_string_view<charT, traits> svconst T& t, size_type pos = npos) constnoexcept;-1- Effects: Creates a variable,
-2- Returns:sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the highest positionxpos
, if possible, such that both of the following conditions hold: […]xpos
if the function can determine such a value forxpos
. Otherwise, returnsnpos
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.
Edit 27.4.3.8.4 [string.compare] as indicated:
template<class T> int compare(basic_string_view<charT, traits> svconst T& t) constnoexcept;-1- Effects: Creates a variable,
-2- Returns: The nonzero result if the result of the comparison is nonzero. Otherwise, returns a value as indicated in Table 63. […]sv
, as if bybasic_string_view<charT, traits> sv = t;
and then dDetermines the effective lengthrlen
of the strings to compare as the smaller ofsize()
andsv.size()
. The function then compares the two strings by callingtraits::compare(data(), sv.data(), rlen)
.-?- Remarks: This function shall not participate in overload resolution unless
-?- Throws: Nothing unless the initialization ofis_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.sv
throws an exception.template<class T> int compare(size_type pos1, size_type n1,basic_string_view<charT, traits> svconst T& t) const;-3- Effects: Equivalent to:
{ basic_string_view<charT, traits> sv = t; return basic_string_view<charT, traits>(data(), size()).substr(pos1, n1).compare(sv); }-?- Remarks: This function shall not participate in overload resolution unless
is_convertible_v<const T&, basic_string_view<charT, traits>>
istrue
andis_convertible_v<const T&, const charT*>
isfalse
.