Movatterモバイル変換


[0]ホーム

URL:



This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofWP status.

3950.std::basic_string_view comparison operators are overspecified

Section: 27.3.2[string.view.synop]Status:WPSubmitter: Giuseppe D'AngeloOpened: 2023-06-21Last modified: 2024-04-02

Priority:Not Prioritized

View all issues withWP status.

Discussion:

The<string_view> synopsis in 27.3.2[string.view.synop] has these signaturesforoperator== andoperator<=>:

//27.3.4[string.view.comparison], non-member comparison functionstemplate<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> x,                            basic_string_view<charT, traits> y) noexcept;template<class charT, class traits>  constexpr see below operator<=>(basic_string_view<charT, traits> x,                                  basic_string_view<charT, traits> y) noexcept;//see 27.3.4[string.view.comparison], sufficient additional overloads of comparison functions

In 27.3.4[string.view.comparison], paragraph 1 states that "Implementationsshall provide sufficient additional overloads" so that all comparisonsbetween abasic_string_view<C, T> object and an object of a typeconvertible tobasic_string_view<C, T> work (with the reasonablesemantics).

The associated Example 1 proposes this implementation strategy foroperator==:

template<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> lhs,                            basic_string_view<charT, traits> rhs) noexcept {    return lhs.compare(rhs) == 0;  }template<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> lhs,                            type_identity_t<basic_string_view<charT, traits>> rhs) noexcept {    return lhs.compare(rhs) == 0;  }

With the current semantics of rewritten candidates for the comparisonoperators, it is however superfluous to actually specify both overloads(the same applies foroperator<=>).

The second overload (usingtype_identity_t) is indeed necessary toimplement the "sufficient additional overloads" part of 27.3.4[string.view.comparison], but it is also sufficient, as all the following cases

can in fact use it (directly, or after being rewritten e.g. with thearguments swapped).

The reason why we still do have both operators seems to be historical;there is an explanation offeredhere by Barry Revzin.

Basically, there were three overloads before a bunch of papers regardingoperator<=> andoperator== were merged:

  1. operator==(bsv,bsv) to deal withsv == sv;

  2. operator==(bsv, type_identity_t<bsv>) and

  3. operator==(type_identity_t<bsv>,bsv) to deal withsv ==convertible_to_sv and vice versa.

Overload (1) was necessary because with only (2) and (3) a call likesv == sv would otherwise be ambiguous. With the adoption of the rewritingrules, overload (3) has been dropped, without realizing that overload(1) would then become redundant.

The specification of these overloads can be greatly simplified byadjusting the signatures to explicitly usetype_identity_t.

[Kona 2023-11-10; move to Ready]

Editorial issue6324provides the changes as a pull request to the draft.

[Tokyo 2024-03-23; Status changed: Voting → WP.]

Proposed resolution:

This wording is relative toN4950.

  1. Modify 27.3.2[string.view.synop], header<string_view> synopsis, as indicated:

    […]//27.3.4[string.view.comparison], non-member comparison functionstemplate<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> x,type_identity_t<basic_string_view<charT, traits>> y) noexcept;template<class charT, class traits>  constexprsee below operator<=>(basic_string_view<charT, traits> x,type_identity_t<basic_string_view<charT, traits>> y) noexcept;//see 27.3.4[string.view.comparison], sufficient additional overloads of comparison functions[…]
  2. Modify 27.3.4[string.view.comparison] as indicated:

    -1- LetS bebasic_string_view<charT, traits>, andsv be an instance ofS. Implementations shall provide sufficient additional overloads markedconstexpr andnoexcept so that an objectt with an implicit conversion toS can be compared according to Table 81 [tab:string.view.comparison.overloads].

    Table 81: Additionalbasic_string_view comparison overloads [tab:string.view.comparison.overloads]
    ExpressionEquivalent to
    t == svS(t) == sv
    sv == tsv == S(t)
    t != svS(t) != sv
    sv != tsv != S(t)
    t < svS(t) < sv
    sv < tsv < S(t)
    t > svS(t) > sv
    sv > tsv > S(t)
    t <= svS(t) <= sv
    sv <= tsv <= S(t)
    t >= svS(t) >= sv
    sv >= tsv >= S(t)
    t <=> svS(t) <=> sv
    sv <=> tsv <=> S(t)

    [Example 1: A sample conforming implementation foroperator== would be:

    template<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> lhs,                            basic_string_view<charT, traits> rhs) noexcept {    return lhs.compare(rhs) == 0;  }template<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> lhs,                            type_identity_t<basic_string_view<charT, traits>> rhs) noexcept {    return lhs.compare(rhs) == 0;  }

    end example]

    template<class charT, class traits>  constexpr bool operator==(basic_string_view<charT, traits> lhs,type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;

    -2-Returns:lhs.compare(rhs) == 0.

    template<class charT, class traits>  constexprsee below operator<=>(basic_string_view<charT, traits> lhs,type_identity_t<basic_string_view<charT, traits>> rhs) noexcept;

    -3- LetR denote the typetraits::comparison_category if thatqualified-id is valid and denotes atype (13.10.3[temp.deduct]), otherwiseR isweak_ordering.

    -4-Mandates:R denotes a comparison category type (17.12.2[cmp.categories]).

    -5-Returns:static_cast<R>(lhs.compare(rhs) <=> 0).

    [Note: The usage oftype_identity_t as parameter ensures that an object of typebasic_string_view<charT, traits> can always be compared with an object of a typeT with an implicit conversion tobasic_string_view<charT, traits>, and vice versa, as per 12.2.2.3[over.match.oper]. —end note]


[8]ページ先頭

©2009-2026 Movatter.jp