21 Strings library [strings]

21.3 String classes [string.classes]

The header <string> defines the basic_­string class template for manipulating varying-length sequences of char-like objects and five typedef-names, string, u8string, u16string, u32string, and wstring, that name the specializations basic_­string<char>, basic_­string<char8_­t>, basic_­string<char16_­t>, basic_­string<char32_­t>, and basic_­string<wchar_­t>, respectively.

21.3.1 Header <string> synopsis [string.syn]

#include <initializer_list>

namespace std {
  // [char.traits], character traits
  template<class charT> struct char_traits;
  template<> struct char_traits<char>;
  template<> struct char_traits<char8_t>;
  template<> struct char_traits<char16_t>;
  template<> struct char_traits<char32_t>;
  template<> struct char_traits<wchar_t>;

  // [basic.string], basic_­string
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_string;

  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const charT* lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const charT* lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(charT lhs,
                const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(charT lhs,
                basic_string<charT, traits, Allocator>&& rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                const charT* rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                const charT* rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(const basic_string<charT, traits, Allocator>& lhs,
                charT rhs);
  template<class charT, class traits, class Allocator>
    basic_string<charT, traits, Allocator>
      operator+(basic_string<charT, traits, Allocator>&& lhs,
                charT rhs);

  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator==(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator!=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);

  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator< (const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator> (const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);

  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator<=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);
  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
                    const basic_string<charT, traits, Allocator>& rhs) noexcept;
  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
                    const charT* rhs);
  template<class charT, class traits, class Allocator>
    bool operator>=(const charT* lhs,
                    const basic_string<charT, traits, Allocator>& rhs);

  // [string.special], swap
  template<class charT, class traits, class Allocator>
    void swap(basic_string<charT, traits, Allocator>& lhs,
              basic_string<charT, traits, Allocator>& rhs)
      noexcept(noexcept(lhs.swap(rhs)));

  // [string.io], inserters and extractors
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      operator>>(basic_istream<charT, traits>& is,
                 basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os,
                 const basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>& is,
              basic_string<charT, traits, Allocator>& str,
              charT delim);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>&& is,
              basic_string<charT, traits, Allocator>& str,
              charT delim);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>& is,
              basic_string<charT, traits, Allocator>& str);
  template<class charT, class traits, class Allocator>
    basic_istream<charT, traits>&
      getline(basic_istream<charT, traits>&& is,
              basic_string<charT, traits, Allocator>& str);

  // [string.erasure], erasure
  template<class charT, class traits, class Allocator, class U>
    void erase(basic_string<charT, traits, Allocator>& c, const U& value);
  template<class charT, class traits, class Allocator, class Predicate>
    void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);

  // basic_­string typedef names
  using string    = basic_string<char>;
  using u8string  = basic_string<char8_t>;
  using u16string = basic_string<char16_t>;
  using u32string = basic_string<char32_t>;
  using wstring   = basic_string<wchar_t>;

  // [string.conversions], numeric conversions
  int stoi(const string& str, size_t* idx = nullptr, int base = 10);
  long stol(const string& str, size_t* idx = nullptr, int base = 10);
  unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10);
  long long stoll(const string& str, size_t* idx = nullptr, int base = 10);
  unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
  float stof(const string& str, size_t* idx = nullptr);
  double stod(const string& str, size_t* idx = nullptr);
  long double stold(const string& str, size_t* idx = nullptr);
  string to_string(int val);
  string to_string(unsigned val);
  string to_string(long val);
  string to_string(unsigned long val);
  string to_string(long long val);
  string to_string(unsigned long long val);
  string to_string(float val);
  string to_string(double val);
  string to_string(long double val);

  int stoi(const wstring& str, size_t* idx = nullptr, int base = 10);
  long stol(const wstring& str, size_t* idx = nullptr, int base = 10);
  unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10);
  long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10);
  unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
  float stof(const wstring& str, size_t* idx = nullptr);
  double stod(const wstring& str, size_t* idx = nullptr);
  long double stold(const wstring& str, size_t* idx = nullptr);
  wstring to_wstring(int val);
  wstring to_wstring(unsigned val);
  wstring to_wstring(long val);
  wstring to_wstring(unsigned long val);
  wstring to_wstring(long long val);
  wstring to_wstring(unsigned long long val);
  wstring to_wstring(float val);
  wstring to_wstring(double val);
  wstring to_wstring(long double val);

  namespace pmr {
    template<class charT, class traits = char_traits<charT>>
      using basic_string = std::basic_string<charT, traits, polymorphic_allocator<charT>>;

    using string    = basic_string<char>;
    using u8string  = basic_string<char8_t>;
    using u16string = basic_string<char16_t>;
    using u32string = basic_string<char32_t>;
    using wstring   = basic_string<wchar_t>;
  }

  // [basic.string.hash], hash support
  template<class T> struct hash;
  template<> struct hash<string>;
  template<> struct hash<u8string>;
  template<> struct hash<u16string>;
  template<> struct hash<u32string>;
  template<> struct hash<wstring>;
  template<> struct hash<pmr::string>;
  template<> struct hash<pmr::u8string>;
  template<> struct hash<pmr::u16string>;
  template<> struct hash<pmr::u32string>;
  template<> struct hash<pmr::wstring>;

  inline namespace literals {
  inline namespace string_literals {
    // [basic.string.literals], suffix for basic_­string literals
    string    operator""s(const char* str, size_t len);
    u8string  operator""s(const char8_t* str, size_t len);
    u16string operator""s(const char16_t* str, size_t len);
    u32string operator""s(const char32_t* str, size_t len);
    wstring   operator""s(const wchar_t* str, size_t len);
  }
  }
}

21.3.2 Class template basic_­string [basic.string]

The class template basic_­string describes objects that can store a sequence consisting of a varying number of arbitrary char-like objects with the first element of the sequence at position zero.
Such a sequence is also called a “string” if the type of the char-like objects that it holds is clear from context.
In the rest of this Clause, the type of the char-like objects held in a basic_­string object is designated by charT.
A specialization of basic_­string is a contiguous container ([container.requirements.general]).
In all cases, [data(), data() + size()] is a valid range, data() + size() points at an object with value charT() (a “null terminator”), and size() <= capacity() is true.
namespace std {
  template<class charT, class traits = char_traits<charT>,
           class Allocator = allocator<charT>>
  class basic_string {
  public:
    // types
    using traits_type            = traits;
    using value_type             = charT;
    using allocator_type         = Allocator;
    using size_type              = typename allocator_traits<Allocator>::size_type;
    using difference_type        = typename allocator_traits<Allocator>::difference_type;
    using pointer                = typename allocator_traits<Allocator>::pointer;
    using const_pointer          = typename allocator_traits<Allocator>::const_pointer;
    using reference              = value_type&;
    using const_reference        = const value_type&;

    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    static const size_type npos  = -1;

    // [string.cons], construct/copy/destroy
    basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
    explicit basic_string(const Allocator& a) noexcept;
    basic_string(const basic_string& str);
    basic_string(basic_string&& str) noexcept;
    basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator());
    basic_string(const basic_string& str, size_type pos, size_type n,
                 const Allocator& a = Allocator());
    template<class T>
      basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
    template<class T>
      explicit basic_string(const T& t, const Allocator& a = Allocator());
    basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
    basic_string(const charT* s, const Allocator& a = Allocator());
    basic_string(size_type n, charT c, const Allocator& a = Allocator());
    template<class InputIterator>
      basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
    basic_string(initializer_list<charT>, const Allocator& = Allocator());
    basic_string(const basic_string&, const Allocator&);
    basic_string(basic_string&&, const Allocator&);

    ~basic_string();
    basic_string& operator=(const basic_string& str);
    basic_string& operator=(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    template<class T>
      basic_string& operator=(const T& t);
    basic_string& operator=(const charT* s);
    basic_string& operator=(charT c);
    basic_string& operator=(initializer_list<charT>);

    // [string.iterators], iterators
    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // [string.capacity], capacity
    size_type size() const noexcept;
    size_type length() const noexcept;
    size_type max_size() const noexcept;
    void resize(size_type n, charT c);
    void resize(size_type n);
    size_type capacity() const noexcept;
    void reserve(size_type res_arg);
    void shrink_to_fit();
    void clear() noexcept;
    [[nodiscard]] bool empty() const noexcept;

    // [string.access], element access
    const_reference operator[](size_type pos) const;
    reference       operator[](size_type pos);
    const_reference at(size_type n) const;
    reference       at(size_type n);

    const charT& front() const;
    charT&       front();
    const charT& back() const;
    charT&       back();

    // [string.modifiers], modifiers
    basic_string& operator+=(const basic_string& str);
    template<class T>
      basic_string& operator+=(const T& t);
    basic_string& operator+=(const charT* s);
    basic_string& operator+=(charT c);
    basic_string& operator+=(initializer_list<charT>);
    basic_string& append(const basic_string& str);
    basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
    template<class T>
      basic_string& append(const T& t);
    template<class T>
      basic_string& append(const T& t, size_type pos, size_type n = npos);
    basic_string& append(const charT* s, size_type n);
    basic_string& append(const charT* s);
    basic_string& append(size_type n, charT c);
    template<class InputIterator>
      basic_string& append(InputIterator first, InputIterator last);
    basic_string& append(initializer_list<charT>);

    void push_back(charT c);

    basic_string& assign(const basic_string& str);
    basic_string& assign(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
    template<class T>
      basic_string& assign(const T& t);
    template<class T>
      basic_string& assign(const T& t, size_type pos, size_type n = npos);
    basic_string& assign(const charT* s, size_type n);
    basic_string& assign(const charT* s);
    basic_string& assign(size_type n, charT c);
    template<class InputIterator>
      basic_string& assign(InputIterator first, InputIterator last);
    basic_string& assign(initializer_list<charT>);

    basic_string& insert(size_type pos, const basic_string& str);
    basic_string& insert(size_type pos1, const basic_string& str,
                         size_type pos2, size_type n = npos);
    template<class T>
      basic_string& insert(size_type pos, const T& t);
    template<class T>
      basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos);
    basic_string& insert(size_type pos, const charT* s, size_type n);
    basic_string& insert(size_type pos, const charT* s);
    basic_string& insert(size_type pos, size_type n, charT c);
    iterator insert(const_iterator p, charT c);
    iterator insert(const_iterator p, size_type n, charT c);
    template<class InputIterator>
      iterator insert(const_iterator p, InputIterator first, InputIterator last);
    iterator insert(const_iterator p, initializer_list<charT>);

    basic_string& erase(size_type pos = 0, size_type n = npos);
    iterator erase(const_iterator p);
    iterator erase(const_iterator first, const_iterator last);

    void pop_back();

    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                          size_type pos2, size_type n2 = npos);
    template<class T>
      basic_string& replace(size_type pos1, size_type n1, const T& t);
    template<class T>
      basic_string& replace(size_type pos1, size_type n1, const T& t,
                            size_type pos2, size_type n2 = npos);
    basic_string& replace(size_type pos, size_type n1, const charT* s, size_type n2);
    basic_string& replace(size_type pos, size_type n1, const charT* s);
    basic_string& replace(size_type pos, size_type n1, size_type n2, charT c);

    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
    template<class T>
      basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
    basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
    template<class InputIterator>
      basic_string& replace(const_iterator i1, const_iterator i2,
                            InputIterator j1, InputIterator j2);
    basic_string& replace(const_iterator, const_iterator, initializer_list<charT>);

    size_type copy(charT* s, size_type n, size_type pos = 0) const;

    void swap(basic_string& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);

    // [string.ops], string operations
    const charT* c_str() const noexcept;
    const charT* data() const noexcept;
    charT* data() noexcept;
    operator basic_string_view<charT, traits>() const noexcept;
    allocator_type get_allocator() const noexcept;

    template<class T>
      size_type find (const T& t, size_type pos = 0) const noexcept(see below);
    size_type find (const basic_string& str, size_type pos = 0) const noexcept;
    size_type find (const charT* s, size_type pos, size_type n) const;
    size_type find (const charT* s, size_type pos = 0) const;
    size_type find (charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type rfind(const T& t, size_type pos = npos) const noexcept(see below);
    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
    size_type rfind(const charT* s, size_type pos, size_type n) const;
    size_type rfind(const charT* s, size_type pos = npos) const;
    size_type rfind(charT c, size_type pos = npos) const noexcept;

    template<class T>
      size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below);
    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
    size_type find_first_of(const charT* s, size_type pos, size_type n) const;
    size_type find_first_of(const charT* s, size_type pos = 0) const;
    size_type find_first_of(charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type find_last_of (const T& t, size_type pos = npos) const noexcept(see below);
    size_type find_last_of (const basic_string& str, size_type pos = npos) const noexcept;
    size_type find_last_of (const charT* s, size_type pos, size_type n) const;
    size_type find_last_of (const charT* s, size_type pos = npos) const;
    size_type find_last_of (charT c, size_type pos = npos) const noexcept;

    template<class T>
      size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below);
    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
    size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
    size_type find_first_not_of(const charT* s, size_type pos = 0) const;
    size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
    template<class T>
      size_type find_last_not_of (const T& t, size_type pos = npos) const noexcept(see below);
    size_type find_last_not_of (const basic_string& str, size_type pos = npos) const noexcept;
    size_type find_last_not_of (const charT* s, size_type pos, size_type n) const;
    size_type find_last_not_of (const charT* s, size_type pos = npos) const;
    size_type find_last_not_of (charT c, size_type pos = npos) const noexcept;

    basic_string substr(size_type pos = 0, size_type n = npos) const;
    template<class T>
      int compare(const T& t) const noexcept(see below);
    template<class T>
      int compare(size_type pos1, size_type n1, const T& t) const;
    template<class T>
      int compare(size_type pos1, size_type n1, const T& t,
                  size_type pos2, size_type n2 = npos) const;
    int compare(const basic_string& str) const noexcept;
    int compare(size_type pos1, size_type n1, const basic_string& str) const;
    int compare(size_type pos1, size_type n1, const basic_string& str,
                size_type pos2, size_type n2 = npos) const;
    int compare(const charT* s) const;
    int compare(size_type pos1, size_type n1, const charT* s) const;
    int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const;

    bool starts_with(basic_string_view<charT, traits> x) const noexcept;
    bool starts_with(charT x) const noexcept;
    bool starts_with(const charT* x) const;
    bool ends_with(basic_string_view<charT, traits> x) const noexcept;
    bool ends_with(charT x) const noexcept;
    bool ends_with(const charT* x) const;
  };

  template<class InputIterator,
           class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
    basic_string(InputIterator, InputIterator, Allocator = Allocator())
      -> basic_string<typename iterator_traits<InputIterator>::value_type,
                      char_traits<typename iterator_traits<InputIterator>::value_type>,
                      Allocator>;

  template<class charT,
           class traits,
           class Allocator = allocator<charT>>
    explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator())
      -> basic_string<charT, traits, Allocator>;

  template<class charT,
           class traits,
           class Allocator = allocator<charT>>
    basic_string(basic_string_view<charT, traits>,
                 typename see below::size_type, typename see below::size_type,
                 const Allocator& = Allocator())
      -> basic_string<charT, traits, Allocator>;
}
A size_­type parameter type in a basic_­string deduction guide refers to the size_­type member type of the type deduced by the deduction guide.

21.3.2.1 General requirements [string.require]

If any operation would cause size() to exceed max_­size(), that operation throws an exception object of type length_­error.
If any member function or operator of basic_­string throws an exception, that function or operator has no other effect on the basic_­string object.
In every specialization basic_­string<charT, traits, Allocator>, the type allocator_­traits<Allocator>::value_­type shall name the same type as charT.
Every object of type basic_­string<charT, traits, Allocator> uses an object of type Allocator to allocate and free storage for the contained charT objects as needed.
The Allocator object used is obtained as described in [container.requirements.general].
In every specialization basic_­string<charT, traits, Allocator>, the type traits shall satisfy the character traits requirements ([char.traits]).
[Note
:
The program is ill-formed if traits::char_­type is not the same type as charT.
end note
]
References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:
  • Passing as an argument to any standard library function taking a reference to non-const basic_­string as an argument.226
  • Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
For example, as an argument to non-member functions swap(), operator>>(), and getline(), or as an argument to basic_­string::swap().

21.3.2.2 Constructors and assignment operators [string.cons]

explicit basic_string(const Allocator& a) noexcept;
Ensures: size() is equal to 0.
basic_string(const basic_string& str); basic_string(basic_string&& str) noexcept;
Effects: Constructs an object whose value is that of str prior to this call.
Remarks: In the second form, str is left in a valid but unspecified state.
basic_string(const basic_string& str, size_type pos, const Allocator& a = Allocator()); basic_string(const basic_string& str, size_type pos, size_type n, const Allocator& a = Allocator());
Effects: Let n be npos for the first overload.
Equivalent to:
basic_string(basic_string_view<charT, traits>(str).substr(pos, n), a)
template<class T> basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator());
Constraints: is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true.
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t; and then behaves the same as:
basic_string(sv.substr(pos, n), a);
template<class T> explicit basic_string(const T& t, const Allocator& a = Allocator());
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Creates a variable, sv, as if by basic_­string_­view<charT, traits> sv = t; and then behaves the same as basic_­string(sv.data(), sv.size(), a).
basic_string(const charT* s, size_type n, const Allocator& a = Allocator());
Expects: [s, s + n) is a valid range.
Effects: Constructs an object whose initial value is the range [s, s + n).
Ensures: size() is equal to n, and traits::compare(data(), s, n) is equal to 0.
basic_string(const charT* s, const Allocator& a = Allocator());
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
[Note
:
This affects class template argument deduction.
end note
]
Effects: Equivalent to: basic_­string(s, traits::length(s), a).
basic_string(size_type n, charT c, const Allocator& a = Allocator());
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
[Note
:
This affects class template argument deduction.
end note
]
Effects: Constructs an object whose value consists of n copies of c.
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Constructs a string from the values in the range [begin, end), as indicated in [tab:containers.sequence.requirements]Table *tab:containers.sequence.requirements.
basic_string(initializer_list<charT> il, const Allocator& a = Allocator());
Effects: Equivalent to basic_­string(il.begin(), il.end(), a).
basic_string(const basic_string& str, const Allocator& alloc); basic_string(basic_string&& str, const Allocator& alloc);
Effects: Constructs an object whose value is that of str prior to this call.
The stored allocator is constructed from alloc.
In the second form, str is left in a valid but unspecified state.
Throws: The second form throws nothing if alloc == str.get_­allocator().
template<class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>> basic_string(InputIterator, InputIterator, Allocator = Allocator()) -> basic_string<typename iterator_traits<InputIterator>::value_type, char_traits<typename iterator_traits<InputIterator>::value_type>, Allocator>;
Constraints: InputIterator is a type that qualifies as an input iterator, and Allocator is a type that qualifies as an allocator ([container.requirements.general]).
template<class charT, class traits, class Allocator = allocator<charT>> explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) -> basic_string<charT, traits, Allocator>; template<class charT, class traits, class Allocator = allocator<charT>> basic_string(basic_string_view<charT, traits>, typename see below::size_type, typename see below::size_type, const Allocator& = Allocator()) -> basic_string<charT, traits, Allocator>;
Constraints: Allocator is a type that qualifies as an allocator ([container.requirements.general]).
basic_string& operator=(const basic_string& str);
Effects: If *this and str are the same object, has no effect.
Otherwise, replaces the value of *this with a copy of str.
Returns: *this.
basic_string& operator=(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.
Returns: *this.
template<class T> basic_string& operator=(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv);
basic_string& operator=(const charT* s);
Effects: Equivalent to: return *this = basic_­string_­view<charT, traits>(s);
basic_string& operator=(charT c);
Effects: Equivalent to:
return *this = basic_string_view<charT, traits>(addressof(c), 1);
basic_string& operator=(initializer_list<charT> il);
Effects: Equivalent to:
return *this = basic_string_view<charT, traits>(il.begin(), il.size());

21.3.2.3 Iterator support [string.iterators]

iterator begin() noexcept; const_iterator begin() const noexcept; const_iterator cbegin() const noexcept;
Returns: An iterator referring to the first character in the string.
iterator end() noexcept; const_iterator end() const noexcept; const_iterator cend() const noexcept;
Returns: An iterator which is the past-the-end value.
reverse_iterator rbegin() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator crbegin() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(end()).
reverse_iterator rend() noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crend() const noexcept;
Returns: An iterator which is semantically equivalent to reverse_­iterator(begin()).

21.3.2.4 Capacity [string.capacity]

size_type size() const noexcept; size_type length() const noexcept;
Returns: A count of the number of char-like objects currently in the string.
Complexity: Constant time.
size_type max_size() const noexcept;
Returns: The largest possible number of char-like objects that can be stored in a basic_­string.
Complexity: Constant time.
void resize(size_type n, charT c);
Effects: Alters the value of *this as follows:
  • If n <= size(), erases the last size() - n elements.
  • If n > size(), appends n - size() copies of c.
void resize(size_type n);
Effects: Equivalent to resize(n, charT()).
size_type capacity() const noexcept;
Returns: The size of the allocated storage in the string.
Complexity: Constant time.
void reserve(size_type res_arg);
Effects: A directive that informs a basic_­string of a planned change in size, so that the storage allocation can be managed accordingly.
After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise.
Reallocation happens at this point if and only if the current capacity is less than the argument of reserve().
Throws: length_­error if res_­arg > max_­size() or any exceptions thrown by allocator_­traits <Allocator>::allocate.
void shrink_to_fit();
Effects: shrink_­to_­fit is a non-binding request to reduce capacity() to size().
[Note
:
The request is non-binding to allow latitude for implementation-specific optimizations.
end note
]
It does not increase capacity(), but may reduce capacity() by causing reallocation.
Complexity: If the size is not equal to the old capacity, linear in the size of the sequence; otherwise constant.
Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence, as well as the past-the-end iterator.
[Note
:
If no reallocation happens, they remain valid.
end note
]
void clear() noexcept;
Effects: Equivalent to: erase(begin(), end());
[[nodiscard]] bool empty() const noexcept;
Effects: Equivalent to: return size() == 0;

21.3.2.5 Element access [string.access]

const_reference operator[](size_type pos) const; reference operator[](size_type pos);
Expects: pos <= size().
Returns: *(begin() + pos) if pos < size().
Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object to any value other than charT() leads to undefined behavior.
Throws: Nothing.
Complexity: Constant time.
const_reference at(size_type pos) const; reference at(size_type pos);
Throws: out_­of_­range if pos >= size().
Returns: operator[](pos).
const charT& front() const; charT& front();
Expects: !empty().
Effects: Equivalent to: return operator[](0);
const charT& back() const; charT& back();
Expects: !empty().
Effects: Equivalent to: return operator[](size() - 1);

21.3.2.6 Modifiers [string.modifiers]

21.3.2.6.1 basic_­string​::​operator+= [string.op.append]

basic_string& operator+=(const basic_string& str);
Effects: Equivalent to: return append(str);
template<class T> basic_string& operator+=(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv);
basic_string& operator+=(const charT* s);
Effects: Equivalent to: return append(s);
basic_string& operator+=(charT c);
Effects: Equivalent to: return append(size_­type{1}, c);
basic_string& operator+=(initializer_list<charT> il);
Effects: Equivalent to: return append(il);

21.3.2.6.2 basic_­string​::​append [string.append]

basic_string& append(const basic_string& str);
Effects: Equivalent to: return append(str.data(), str.size());
basic_string& append(const basic_string& str, size_type pos, size_type n = npos);
Effects: Equivalent to:
return append(basic_string_view<charT, traits>(str).substr(pos, n));
template<class T> basic_string& append(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv.data(), sv.size());
template<class T> basic_string& append(const T& t, size_type pos, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return append(sv.substr(pos, n));
basic_string& append(const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Effects: Appends a copy of the range [s, s + n) to the string.
Returns: *this.
basic_string& append(const charT* s);
Effects: Equivalent to: return append(s, traits::length(s));
basic_string& append(size_type n, charT c);
Effects: Appends n copies of c to the string.
Returns: *this.
template<class InputIterator> basic_string& append(InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return append(basic_­string(first, last, get_­allocator()));
basic_string& append(initializer_list<charT> il);
Effects: Equivalent to: return append(il.begin(), il.size());
void push_back(charT c);
Effects: Equivalent to append(size_­type{1}, c).

21.3.2.6.3 basic_­string​::​assign [string.assign]

basic_string& assign(const basic_string& str);
Effects: Equivalent to: return *this = str;
basic_string& assign(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Effects: Equivalent to: return *this = std::move(str);
basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
Effects: Equivalent to:
return assign(basic_string_view<charT, traits>(str).substr(pos, n));
template<class T> basic_string& assign(const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv.data(), sv.size());
template<class T> basic_string& assign(const T& t, size_type pos, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return assign(sv.substr(pos, n));
basic_string& assign(const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n).
Returns: *this.
basic_string& assign(const charT* s);
Effects: Equivalent to: return assign(s, traits::length(s));
basic_string& assign(initializer_list<charT> il);
Effects: Equivalent to: return assign(il.begin(), il.size());
basic_string& assign(size_type n, charT c);
Effects: Equivalent to:
clear();
resize(n, c);
return *this;
template<class InputIterator> basic_string& assign(InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return assign(basic_­string(first, last, get_­allocator()));

21.3.2.6.4 basic_­string​::​insert [string.insert]

basic_string& insert(size_type pos, const basic_string& str);
Effects: Equivalent to: return insert(pos, str.data(), str.size());
basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos);
Effects: Equivalent to:
return insert(pos1, basic_string_view<charT, traits>(str), pos2, n);
template<class T> basic_string& insert(size_type pos, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return insert(pos, sv.data(), sv.size());
template<class T> basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return insert(pos1, sv.substr(pos2, n));
basic_string& insert(size_type pos, const charT* s, size_type n);
Expects: [s, s + n) is a valid range.
Throws:
  • out_­of_­range if pos > size(),
  • length_­error if n > max_­size() - size(), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Inserts a copy of the range [s, s + n) immediately before the character at position pos if pos < size(), or otherwise at the end of the string.
Returns: *this.
basic_string& insert(size_type pos, const charT* s);
Effects: Equivalent to: return insert(pos, s, traits::length(s));
basic_string& insert(size_type pos, size_type n, charT c);
Effects: Inserts n copies of c before the character at position pos if pos < size(), or otherwise at the end of the string.
Returns: *this
Throws:
  • out_­of_­range if pos > size(),
  • length_­error if n > max_­size() - size(), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
iterator insert(const_iterator p, charT c);
Expects: p is a valid iterator on *this.
Effects: Inserts a copy of c at the position p.
Returns: An iterator which refers to the inserted character.
iterator insert(const_iterator p, size_type n, charT c);
Expects: p is a valid iterator on *this.
Effects: Inserts n copies of c at the position p.
Returns: An iterator which refers to the first inserted character, or p if n == 0.
template<class InputIterator> iterator insert(const_iterator p, InputIterator first, InputIterator last);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Expects: p is a valid iterator on *this.
Effects: Equivalent to insert(p - begin(), basic_­string(first, last, get_­allocator())).
Returns: An iterator which refers to the first inserted character, or p if first == last.
iterator insert(const_iterator p, initializer_list<charT> il);
Effects: Equivalent to: return insert(p, il.begin(), il.end());

21.3.2.6.5 basic_­string​::​erase [string.erase]

basic_string& erase(size_type pos = 0, size_type n = npos);
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
Removes the characters in the range [begin() + pos, begin() + pos + xlen).
Returns: *this.
iterator erase(const_iterator p);
Expects: p is a valid dereferenceable iterator on *this.
Throws: Nothing.
Effects: Removes the character referred to by p.
Returns: An iterator which points to the element immediately following p prior to the element being erased.
If no such element exists, end() is returned.
iterator erase(const_iterator first, const_iterator last);
Expects: first and last are valid iterators on *this.
[first, last) is a valid range.
Throws: Nothing.
Effects: Removes the characters in the range [first, last).
Returns: An iterator which points to the element pointed to by last prior to the other elements being erased.
If no such element exists, end() is returned.
void pop_back();
Expects: !empty().
Throws: Nothing.
Effects: Equivalent to erase(end() - 1).

21.3.2.6.6 basic_­string​::​replace [string.replace]

basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
Effects: Equivalent to: return replace(pos1, n1, str.data(), str.size());
basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos);
Effects: Equivalent to:
return replace(pos1, n1, basic_string_view<charT, traits>(str).substr(pos2, n2));
template<class T> basic_string& replace(size_type pos1, size_type n1, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(pos1, n1, sv.data(), sv.size());
template<class T> basic_string& replace(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(pos1, n1, sv.substr(pos2, n2));
basic_string& replace(size_type pos1, size_type n1, const charT* s, size_type n2);
Expects: [s, s + n2) is a valid range.
Throws:
  • out_­of_­range if pos1 > size(),
  • length_­error if the length of the resulting string would exceed max_­size() (see below), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Determines the effective length xlen of the string to be removed as the smaller of n1 and size() - pos1.
If size() - xlen >= max_­size() - n2 throws length_­error.
Otherwise, the function replaces the characters in the range [begin() + pos1, begin() + pos1 + xlen) with a copy of the range [s, s + n2).
Returns: *this.
basic_string& replace(size_type pos, size_type n, const charT* s);
Effects: Equivalent to: return replace(pos, n, s, traits::length(s));
basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
Throws:
  • out_­of_­range if pos1 > size(),
  • length_­error if the length of the resulting string would exceed max_­size() (see below), or
  • any exceptions thrown by allocator_­traits<Allocator>::allocate.
Effects: Determines the effective length xlen of the string to be removed as the smaller of n1 and size() - pos1.
If size() - xlen >= max_­size() - n2 throws length_­error.
Otherwise, the function replaces the characters in the range [begin() + pos1, begin() + pos1 + xlen) with n2 copies of c.
Returns: *this.
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(str));
template<class T> basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Expects: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Equivalent to:
basic_string_view<charT, traits> sv = t;
return replace(i1 - begin(), i2 - i1, sv.data(), sv.size());
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s, size_type n);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(s, n));
basic_string& replace(const_iterator i1, const_iterator i2, const charT* s);
Effects: Equivalent to: return replace(i1, i2, basic_­string_­view<charT, traits>(s));
basic_string& replace(const_iterator i1, const_iterator i2, size_type n, charT c);
Expects: [begin(), i1) and [i1, i2) are valid ranges.
Effects: Equivalent to: return replace(i1 - begin(), i2 - i1, n, c);
template<class InputIterator> basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
Constraints: InputIterator is a type that qualifies as an input iterator ([container.requirements.general]).
Effects: Equivalent to: return replace(i1, i2, basic_­string(j1, j2, get_­allocator()));
basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> il);
Effects: Equivalent to: return replace(i1, i2, il.begin(), il.size());

21.3.2.6.7 basic_­string​::​copy [string.copy]

size_type copy(charT* s, size_type n, size_type pos = 0) const;
Effects: Equivalent to: return basic_­string_­view<charT, traits>(*this).copy(s, n, pos);
[Note
:
This does not terminate s with a null object.
end note
]

21.3.2.6.8 basic_­string​::​swap [string.swap]

void swap(basic_string& s) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);
Expects: allocator_­traits<Allocator>::propagate_­on_­container_­swap::value is true or get_­allocator() == s.get_­allocator().
Ensures: *this contains the same sequence of characters that was in s, s contains the same sequence of characters that was in *this.
Throws: Nothing.
Complexity: Constant time.

21.3.2.7 String operations [string.ops]

21.3.2.7.1 Accessors [string.accessors]

const charT* c_str() const noexcept; const charT* data() const noexcept;
Returns: A pointer p such that p + i == addressof(operator[](i)) for each i in [0, size()].
Complexity: Constant time.
Remarks: The program shall not modify any of the values stored in the character array; otherwise, the behavior is undefined.
charT* data() noexcept;
Returns: A pointer p such that p + i == addressof(operator[](i)) for each i in [0, size()].
Complexity: Constant time.
Remarks: The program shall not modify the value stored at p + size() to any value other than charT(); otherwise, the behavior is undefined.
operator basic_string_view<charT, traits>() const noexcept;
Effects: Equivalent to: return basic_­string_­view<charT, traits>(data(), size());
allocator_type get_allocator() const noexcept;
Returns: A copy of the Allocator object used to construct the string or, if that allocator has been replaced, a copy of the most recent replacement.

21.3.2.7.2 Searching [string.find]

Let F be one of find, rfind, find_­first_­of, find_­last_­of, find_­first_­not_­of, and find_­last_­not_­of.
  • Each member function of the form
    size_type F(const basic_string& str, size_type pos) const noexcept;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(str), pos);
  • Each member function of the form
    size_type F(const charT* s, size_type pos) const;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(s), pos);
  • Each member function of the form
    size_type F(const charT* s, size_type pos, size_type n) const;
    
    has effects equivalent to: return F(basic_­string_­view<charT, traits>(s, n), pos);
  • Each member function of the form
    size_type F(charT c, size_type pos) const noexcept;
    
    has effects equivalent to:
    return F(basic_string_view<charT, traits>(addressof(c), 1), pos);
    
template<class T> size_type find(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type rfind(const T& t, size_type pos = npos) const noexcept(see below); template<class T> size_type find_first_of(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type find_last_of(const T& t, size_type pos = npos) const noexcept(see below); template<class T> size_type find_first_not_of(const T& t, size_type pos = 0) const noexcept(see below); template<class T> size_type find_last_not_of(const T& t, size_type pos = npos) const noexcept(see below);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
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);
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­convertible_­v<const T&, basic_­string_­view<charT, traits>>.

21.3.2.7.3 basic_­string​::​substr [string.substr]

basic_string substr(size_type pos = 0, size_type n = npos) const;
Throws: out_­of_­range if pos > size().
Effects: Determines the effective length rlen of the string to copy as the smaller of n and size() - pos.
Returns: basic_­string(data()+pos, rlen).

21.3.2.7.4 basic_­string​::​compare [string.compare]

template<class T> int compare(const T& t) const noexcept(see below);
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to: return basic_­string_­view<charT, traits>(*this).compare(t);
Remarks: The expression inside noexcept is equivalent to is_­nothrow_­convertible_­v<const T&, basic_­string_­view<charT, traits>>.
template<class T> int compare(size_type pos1, size_type n1, const T& t) const;
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
return basic_string_view<charT, traits>(*this).substr(pos1, n1).compare(t);
template<class T> int compare(size_type pos1, size_type n1, const T& t, size_type pos2, size_type n2 = npos) const;
Constraints:
  • is_­convertible_­v<const T&, basic_­string_­view<charT, traits>> is true and
  • is_­convertible_­v<const T&, const charT*> is false.
Effects: Equivalent to:
basic_string_view<charT, traits> s = *this, sv = t;
return s.substr(pos1, n1).compare(sv.substr(pos2, n2));
int compare(const basic_string& str) const noexcept;
Effects: Equivalent to: return compare(basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str) const;
Effects: Equivalent to: return compare(pos1, n1, basic_­string_­view<charT, traits>(str));
int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2 = npos) const;
Effects: Equivalent to:
return compare(pos1, n1, basic_string_view<charT, traits>(str), pos2, n2);
int compare(const charT* s) const;
Effects: Equivalent to: return compare(basic_­string_­view<charT, traits>(s));
int compare(size_type pos, size_type n1, const charT* s) const;
Effects: Equivalent to: return compare(pos, n1, basic_­string_­view<charT, traits>(s));
int compare(size_type pos, size_type n1, const charT* s, size_type n2) const;
Effects: Equivalent to: return compare(pos, n1, basic_­string_­view<charT, traits>(s, n2));

21.3.2.7.5 basic_­string​::​starts_­with [string.starts.with]

bool starts_with(basic_string_view<charT, traits> x) const noexcept; bool starts_with(charT x) const noexcept; bool starts_with(const charT* x) const;
Effects: Equivalent to:
return basic_string_view<charT, traits>(data(), size()).starts_with(x);

21.3.2.7.6 basic_­string​::​ends_­with [string.ends.with]

bool ends_with(basic_string_view<charT, traits> x) const noexcept; bool ends_with(charT x) const noexcept; bool ends_with(const charT* x) const;
Effects: Equivalent to:
return basic_string_view<charT, traits>(data(), size()).ends_with(x);

21.3.3 Non-member functions [string.nonmembers]

21.3.3.1 operator+ [string.op.plus]

template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Effects: Equivalent to:
basic_string<charT, traits, Allocator> r = lhs;
r.append(rhs);
return r;
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs);
Effects: Equivalent to:
lhs.append(rhs);
return std::move(lhs);
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, basic_string<charT, traits, Allocator>&& rhs);
Effects: Equivalent to:
lhs.append(rhs);
return std::move(lhs);
except that both lhs and rhs are left in valid but unspecified states.
[Note
:
If lhs and rhs have equal allocators, the implementation may move from either.
end note
]
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>&& rhs); template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT* lhs, basic_string<charT, traits, Allocator>&& rhs);
Effects: Equivalent to:
rhs.insert(0, lhs);
return std::move(rhs);
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
Effects: Equivalent to:
basic_string<charT, traits, Allocator> r = rhs;
r.insert(0, lhs);
return r;
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(charT lhs, const basic_string<charT, traits, Allocator>& rhs);
Effects: Equivalent to:
basic_string<charT, traits, Allocator> r = rhs;
r.insert(r.begin(), lhs);
return r;
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(charT lhs, basic_string<charT, traits, Allocator>&& rhs);
Effects: Equivalent to:
rhs.insert(rhs.begin(), lhs);
return std::move(rhs);
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
Effects: Equivalent to:
basic_string<charT, traits, Allocator> r = lhs;
r.push_back(rhs);
return r;
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(basic_string<charT, traits, Allocator>&& lhs, charT rhs);
Effects: Equivalent to:
lhs.push_back(rhs);
return std::move(lhs);

21.3.3.2 Non-member comparison functions [string.cmp]

template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs); template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept; template<class charT, class traits, class Allocator> bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs); template<class charT, class traits, class Allocator> bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
Effects: Let op be the operator.
Equivalent to:
  return basic_string_view<charT, traits>(lhs) op basic_string_view<charT, traits>(rhs);

21.3.3.3 swap [string.special]

template<class charT, class traits, class Allocator> void swap(basic_string<charT, traits, Allocator>& lhs, basic_string<charT, traits, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)));
Effects: Equivalent to lhs.swap(rhs).

21.3.3.4 Inserters and extractors [string.io]

template<class charT, class traits, class Allocator> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
Effects: Behaves as a formatted input function.
After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c).
If is.width() is greater than zero, the maximum number n of characters appended is is.width(); otherwise n is str.max_­size().
Characters are extracted and appended until any of the following occurs:
  • n characters are stored;
  • end-of-file occurs on the input sequence;
  • isspace(c, is.getloc()) is true for the next available input character c.
After the last character (if any) is extracted, is.width(0) is called and the sentry object is destroyed.
If the function extracts no characters, it calls is.setstate(ios::failbit), which may throw ios_­base::failure ([iostate.flags]).
Returns: is.
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
Effects: Equivalent to: return os << basic_­string_­view<charT, traits>(str);
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str, charT delim); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is, basic_string<charT, traits, Allocator>& str, charT delim);
Effects: Behaves as an unformatted input function, except that it does not affect the value returned by subsequent calls to basic_­istream<>::gcount().
After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c) until any of the following occurs:
  • end-of-file occurs on the input sequence (in which case, the getline function calls is.setstate(​ios_­base::eofbit)).
  • traits::eq(c, delim) for the next available input character c (in which case, c is extracted but not appended) ([iostate.flags])
  • str.max_­size() characters are stored (in which case, the function calls is.setstate(ios_­base::failbit)) ([iostate.flags])
The conditions are tested in the order shown.
In any case, after the last character is extracted, the sentry object is destroyed.
If the function extracts no characters, it calls is.setstate(ios_­base::failbit) which may throw ios_­base::failure ([iostate.flags]).
Returns: is.
template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>&& is, basic_string<charT, traits, Allocator>& str);
Returns: getline(is, str, is.widen('\n')).

21.3.3.5 Erasure [string.erasure]

template<class charT, class traits, class Allocator, class U> void erase(basic_string<charT, traits, Allocator>& c, const U& value);
Effects: Equivalent to: c.erase(remove(c.begin(), c.end(), value), c.end());
template<class charT, class traits, class Allocator, class Predicate> void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred);
Effects: Equivalent to: c.erase(remove_­if(c.begin(), c.end(), pred), c.end());

21.3.4 Numeric conversions [string.conversions]

int stoi(const string& str, size_t* idx = nullptr, int base = 10); long stol(const string& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const string& str, size_t* idx = nullptr, int base = 10); long long stoll(const string& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const string& str, size_t* idx = nullptr, int base = 10);
Effects: The first two functions call strtol(str.c_­str(), ptr, base), and the last three functions call strtoul(str.c_­str(), ptr, base), strtoll(str.c_­str(), ptr, base), and strtoull(​str.c_­str(), ptr, base), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed.
Throws out_­of_­range if strtol, strtoul, strtoll or strtoull sets errno to ERANGE, or if the converted value is outside the range of representable values for the return type.
float stof(const string& str, size_t* idx = nullptr); double stod(const string& str, size_t* idx = nullptr); long double stold(const string& str, size_t* idx = nullptr);
Effects: These functions call strtof(str.c_­str(), ptr), strtod(str.c_­str(), ptr), and strtold(​str.c_­str(), ptr), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if strtof, strtod, or strtold reports that no conversion could be performed.
Throws out_­of_­range if strtof, strtod, or strtold sets errno to ERANGE or if the converted value is outside the range of representable values for the return type.
string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val);
Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size.
int stoi(const wstring& str, size_t* idx = nullptr, int base = 10); long stol(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long stoul(const wstring& str, size_t* idx = nullptr, int base = 10); long long stoll(const wstring& str, size_t* idx = nullptr, int base = 10); unsigned long long stoull(const wstring& str, size_t* idx = nullptr, int base = 10);
Effects: The first two functions call wcstol(str.c_­str(), ptr, base), and the last three functions call wcstoul(str.c_­str(), ptr, base), wcstoll(str.c_­str(), ptr, base), and wcstoull(​str.c_­str(), ptr, base), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if wcstol, wcstoul, wcstoll, or wcstoull reports that no conversion could be performed.
Throws out_­of_­range if the converted value is outside the range of representable values for the return type.
float stof(const wstring& str, size_t* idx = nullptr); double stod(const wstring& str, size_t* idx = nullptr); long double stold(const wstring& str, size_t* idx = nullptr);
Effects: These functions call wcstof(str.c_­str(), ptr), wcstod(str.c_­str(), ptr), and wcstold(​str.c_­str(), ptr), respectively.
Each function returns the converted result, if any.
The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx.
If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: The converted result.
Throws: invalid_­argument if wcstof, wcstod, or wcstold reports that no conversion could be performed.
Throws out_­of_­range if wcstof, wcstod, or wcstold sets errno to ERANGE.
wstring to_wstring(int val); wstring to_wstring(unsigned val); wstring to_wstring(long val); wstring to_wstring(unsigned long val); wstring to_wstring(long long val); wstring to_wstring(unsigned long long val); wstring to_wstring(float val); wstring to_wstring(double val); wstring to_wstring(long double val);
Returns: Each function returns a wstring object holding the character representation of the value of its argument that would be generated by calling swprintf(buf, buffsz, fmt, val) with a format specifier of L"%d", L"%u", L"%ld", L"%lu", L"%lld", L"%llu", L"%f", L"%f", or L"%Lf", respectively, where buf designates an internal character buffer of sufficient size buffsz.

21.3.5 Hash support [basic.string.hash]

template<> struct hash<string>; template<> struct hash<u8string>; template<> struct hash<u16string>; template<> struct hash<u32string>; template<> struct hash<wstring>; template<> struct hash<pmr::string>; template<> struct hash<pmr::u8string>; template<> struct hash<pmr::u16string>; template<> struct hash<pmr::u32string>; template<> struct hash<pmr::wstring>;
If S is one of these string types, SV is the corresponding string view type, and s is an object of type S, then hash<S>()(s) == hash<SV>()(SV(s)).

21.3.6 Suffix for basic_­string literals [basic.string.literals]

string operator""s(const char* str, size_t len);
Returns: string{str, len}.
u8string operator""s(const char8_t* str, size_t len);
Returns: u8string{str, len}.
u16string operator""s(const char16_t* str, size_t len);
Returns: u16string{str, len}.
u32string operator""s(const char32_t* str, size_t len);
Returns: u32string{str, len}.
wstring operator""s(const wchar_t* str, size_t len);
Returns: wstring{str, len}.
[Note
:
The same suffix s is used for chrono::duration literals denoting seconds but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals.
end note
]