4259. P1148R0 changed the return values of searching functions of std::basic_string on some platforms

Section: 27.4.3.8.2 [string.find] Status: New Submitter: Jiang An Opened: 2025-05-05 Last modified: 2025-06-14

Priority: Not Prioritized

View other active issues in [string.find].

View all other issues in [string.find].

View all issues with New status.

Discussion:

P1148R0 respecified the searching functions of std::basic_string to return corresponding string view type's npos member constant (equal to std::size_t(-1)), converted to the string type S's member S::size_type, when the search fails. Before the change, S::npos (equal to S::size_type(-1)) was returned on failure.

On platforms where std::size_t isn't the widest unsigned integer type (e.g. on usual 32-bit platforms), the return value can change. Because there can be an allocator with a wider size_type, and when the basic_string type S uses such an allocator, S::size_type is specified to be that type, which in turn makes S::size_type(std::size_t(-1)) not equal to S::size_type(-1).

Do we want to restore the old return values?

Previous resolution [SUPERSEDED]:

This wording is relative to N5008.

  1. Modify 27.4.3.8.2 [string.find] as indicated:

    template<class T>
      constexpr size_type find(const T& t, size_type pos = 0) const noexcept(see below);
    […]
    template<class T>
      constexpr size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(see below);
    

    -2- Constraints: […]

    -3- Effects: Let G be the name of the function. Equivalent to:

    basic_string_view<charT, traits> s = *this, sv = t;
    return s.G(sv, pos);
    if (auto result = s.G(sv, pos); result == size_t(-1))
      return npos;
    else
      return result;
    

[2025-06-10, reflector discussion]

During reflector discussion of this issue there was a preference to adjust the proposed wording to use s.npos instead of size_t(-1).

Proposed resolution:

This wording is relative to N5008.

  1. Modify 27.4.3.8.2 [string.find] as indicated:

    template<class T>
      constexpr size_type find(const T& t, size_type pos = 0) const noexcept(see below);
    […]
    template<class T>
      constexpr size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(see below);
    

    -2- Constraints: […]

    -3- Effects: Let G be the name of the function. Equivalent to:

    basic_string_view<charT, traits> s = *this, sv = t;
    return s.G(sv, pos);
    if (auto result = s.G(sv, pos); result == s.npos)
      return npos;
    else
      return result;