Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/header/string"

From cppreference.com
< cpp‎ | header
m (Includes)
(move synopsis to template)
 
(12 intermediate revisions by 7 users not shown)
Line 4: Line 4:
 
This header is part of the [[cpp/string|strings]] library.
 
This header is part of the [[cpp/string|strings]] library.
  
===Includes===
 
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc | {{header|initializer_list}} {{mark since c++11}} }}
+
{{dsc h1|Includes}}
{{dsc | {{header|compare}} {{mark since c++20}} }}
+
{{dsc inc|cpp/header/dsc compare}}
{{dsc end}}
+
{{dsc inc|cpp/header/dsc initializer_list}}
  
===Classes===
+
{{dsc h1|Classes}}
{{dsc begin}}
+
{{dsc tclass|cpp/string/char_traits|Class Template which describes properties of a character type}}
{{dsc hitem | Name | Description}}
+
{{dsc|{{c/core|std::char_traits<char>}}|{{mark ptclass}}}}
{{dsc| {{lc|std::char_traits}} | Class Template which describes properties of a character type {{mark tclass}} }}
+
{{dsc|{{c/core|std::char_traits<wchar_t>}}|{{mark ptclass}}}}
{{dsc| {{c|std::char_traits<char>}} | {{mark ptclass}} }}
+
{{dsc|{{c/core|std::char_traits<char8_t>}} {{mark c++20}}|{{mark ptclass}}}}
{{dsc| {{c|std::char_traits<wchar_t>}} | {{mark ptclass}} }}
+
{{dsc|{{c/core|std::char_traits<char16_t>}} {{mark c++11}}|{{mark ptclass}}}}
{{dsc| {{c|std::char_traits<char8_t>}} {{mark c++20}} | {{mark ptclass}} }}
+
{{dsc|{{c/core|std::char_traits<char32_t>}} {{mark c++11}}|{{mark ptclass}}}}
{{dsc| {{c|std::char_traits<char16_t>}} {{mark c++11}} | {{mark ptclass}} }}
+
{{dsc| {{c|std::char_traits<char32_t>}} {{mark c++11}} | {{mark ptclass}} }}
+
  
{{dsc| {{lc|std::basic_string}} | Class template representing a text string object {{mark tclass}} }}
+
{{dsc inc|cpp/string/dsc basic_string}}
{{dsc| {{lc|std::string}} | {{c|std::basic_string<char>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::string}}|{{c/core|std::basic_string<char>}} {{mark typedef}}}}
{{dsc | {{lc|std::u8string}} {{mark c++20}} | {{c|std::basic_string<char8_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::u8string}} {{mark c++20}}|{{c/core|std::basic_string<char8_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::u16string}} {{mark c++11}} | {{c|std::basic_string<char16_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::u16string}} {{mark c++11}}|{{c/core|std::basic_string<char16_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::u32string}} {{mark c++11}} | {{c|std::basic_string<char32_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::u32string}} {{mark c++11}}|{{c/core|std::basic_string<char32_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::wstring}} | {{c|std::basic_string<wchar_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::wstring}}|{{c/core|std::basic_string<wchar_t>}} {{mark typedef}}}}
  
{{dsc | {{lc|std::pmr::basic_string}} {{mark c++17}} | {{mark talias}} }}
+
{{dsc|{{lc|std::pmr::basic_string}} {{mark c++17}}|{{mark talias}}}}
  
{{dsc| {{lc|std::pmr::string}} {{mark c++17}} | {{c|std::pmr::basic_string<char>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::pmr::string}} {{mark c++17}}|{{c/core|std::pmr::basic_string<char>}} {{mark typedef}}}}
{{dsc | {{lc|std::pmr::u8string}} {{mark c++20}} | {{c|std::pmr::basic_string<char8_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::pmr::u8string}} {{mark c++20}}|{{c/core|std::pmr::basic_string<char8_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::pmr::u16string}} {{mark c++17}} | {{c|std::pmr::basic_string<char16_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::pmr::u16string}} {{mark c++17}}|{{c/core|std::pmr::basic_string<char16_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::pmr::u32string}} {{mark c++17}} | {{c|std::pmr::basic_string<char32_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::pmr::u32string}} {{mark c++17}}|{{c/core|std::pmr::basic_string<char32_t>}} {{mark typedef}}}}
{{dsc | {{lc|std::pmr::wstring}} {{mark c++17}} | {{c|std::pmr::basic_string<wchar_t>}} {{mark typedef}} }}
+
{{dsc|{{lc|std::pmr::wstring}} {{mark c++17}}|{{c/core|std::pmr::basic_string<wchar_t>}} {{mark typedef}}}}
  
{{dsc | {{c|std::hash<std::string>}} {{mark c++11}} | {{mark ptclass}} }}
+
{{cpp/string/basic_string/dsc hash}}
{{dsc | {{c|std::hash<std::u8string>}} {{mark c++20}} | {{mark ptclass}} }}
+
{{dsc | {{c|std::hash<std::u16string>}} {{mark c++11}} | {{mark ptclass}} }}
+
{{dsc | {{c|std::hash<std::u32string>}} {{mark c++11}} | {{mark ptclass}}}}
+
{{dsc | {{c|std::hash<std::wstring>}}  {{mark c++11}} | {{mark ptclass}}}}
+
  
{{dsc | {{c|std::hash<std::pmr::string>}} {{mark c++20}} | {{mark ptclass}} }}
+
{{dsc h1|Functions}}
{{dsc | {{c|std::hash<std::pmr::u8string>}} {{mark c++20}} | {{mark ptclass}} }}
+
{{dsc inc|cpp/string/basic_string/dsc operator+}}
{{dsc | {{c|std::hash<std::pmr::u16string>}} {{mark c++20}} | {{mark ptclass}} }}
+
{{dsc inc|cpp/string/basic_string/dsc operator_cmp}}
{{dsc | {{c|std::hash<std::pmr::u32string>}} {{mark c++20}} | {{mark ptclass}}}}
+
{{dsc inc|cpp/string/basic_string/dsc swap2}}
{{dsc | {{c|std::hash<std::pmr::wstring>}}  {{mark c++20}} | {{mark ptclass}}}}
+
{{dsc inc|cpp/container/dsc erase seq|basic_string}}
{{dsc end}}
+
  
===Functions===
+
{{dsc h2|Input/output}}
 +
{{dsc inc|cpp/string/basic_string/dsc operator_ltltgtgt}}
 +
{{dsc inc|cpp/string/basic_string/dsc getline}}
  
{{dsc begin}}
+
{{dsc h2|Numeric conversions}}
{{dsc inc | cpp/string/basic_string/dsc operator+}}
+
{{dsc inc|cpp/string/basic_string/dsc stol}}
{{dsc inc | cpp/string/basic_string/dsc operator_cmp}}
+
{{dsc inc|cpp/string/basic_string/dsc stoul}}
{{dsc inc | cpp/string/basic_string/dsc swap2}}
+
{{dsc inc|cpp/string/basic_string/dsc stof}}
 +
{{dsc inc|cpp/string/basic_string/dsc to_string}}
 +
{{dsc inc|cpp/string/basic_string/dsc to_wstring}}
  
{{dsc h2 | Input/output}}
+
{{dsc h2|Range access}}
{{dsc inc | cpp/string/basic_string/dsc operator_ltltgtgt}}
+
{{dsc inc|cpp/iterator/dsc begin}}
{{dsc inc | cpp/string/basic_string/dsc getline}}
+
{{dsc inc|cpp/iterator/dsc end}}
 +
{{dsc inc|cpp/iterator/dsc rbegin}}
 +
{{dsc inc|cpp/iterator/dsc rend}}
 +
{{dsc inc|cpp/iterator/dsc size}}
 +
{{dsc inc|cpp/iterator/dsc empty}}
 +
{{dsc inc|cpp/iterator/dsc data}}
  
{{dsc h2 | Numeric conversions}}
+
{{dsc h2|Literals}}
{{dsc inc | cpp/string/basic_string/dsc stol}}
+
{{dsc namespace|std::literals::string_literals|inline=true}}
{{dsc inc | cpp/string/basic_string/dsc stoul}}
+
{{dsc inc|cpp/string/basic_string/dsc operator""s}}
{{dsc inc | cpp/string/basic_string/dsc stof}}
+
{{dsc inc | cpp/string/basic_string/dsc to_string}}
+
{{dsc inc | cpp/string/basic_string/dsc to_wstring}}
+
{{dsc end}}
+
 
+
===Literals===
+
{{dsc begin}}
+
{{dsc namespace | std::literals::string_literals | inline=true }}
+
{{dsc inc | cpp/string/basic_string/dsc operator""s}}
+
 
{{dsc end}}
 
{{dsc end}}
  
 
===Synopsis===
 
===Synopsis===
{{source|1=
+
{{cpp/synopsis/string}}
#include <compare>
+
#include <initializer_list>
+
 
+
namespace std {
+
  // 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
+
  template<class CharT, class Traits = char_traits<CharT>,
+
          class Allocator = allocator<CharT>>
+
    class basic_string;
+
 
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr 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>
+
    constexpr 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>
+
    constexpr 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>
+
    constexpr 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>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(const CharT* lhs,
+
                const basic_string<CharT, Traits, Allocator>& rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(const CharT* lhs,
+
                basic_string<CharT, Traits, Allocator>&& rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(CharT lhs,
+
                const basic_string<CharT, Traits, Allocator>& rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(CharT lhs,
+
                basic_string<CharT, Traits, Allocator>&& rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(const basic_string<CharT, Traits, Allocator>& lhs,
+
                const CharT* rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(basic_string<CharT, Traits, Allocator>&& lhs,
+
                const CharT* rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(const basic_string<CharT, Traits, Allocator>& lhs,
+
                CharT rhs);
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr basic_string<CharT, Traits, Allocator>
+
      operator+(basic_string<CharT, Traits, Allocator>&& lhs,
+
                CharT rhs);
+
 
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr bool
+
      operator==(const basic_string<CharT, Traits, Allocator>& lhs,
+
                const basic_string<CharT, Traits, Allocator>& rhs) noexcept;
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr bool operator==(const basic_string<CharT, Traits, Allocator>& lhs,
+
                              const CharT* rhs);
+
 
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr /* see description */
+
      operator<=>(const basic_string<CharT, Traits, Allocator>& lhs,
+
                  const basic_string<CharT, Traits, Allocator>& rhs) noexcept;
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr /* see description */
+
      operator<=>(const basic_string<CharT, Traits, Allocator>& lhs,
+
                  const CharT* rhs);
+
 
+
  // swap
+
  template<class CharT, class Traits, class Allocator>
+
    constexpr void
+
      swap(basic_string<CharT, Traits, Allocator>& lhs,
+
          basic_string<CharT, Traits, Allocator>& rhs)
+
        noexcept(noexcept(lhs.swap(rhs)));
+
 
+
  // 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);
+
 
+
  // erasure
+
  template<class CharT, class Traits, class Allocator, class U>
+
    constexpr typename basic_string<CharT, Traits, Allocator>::size_type
+
      erase(basic_string<CharT, Traits, Allocator>& c, const U& value);
+
  template<class CharT, class Traits, class Allocator, class Pred>
+
    constexpr typename basic_string<CharT, Traits, Allocator>::size_type
+
      erase_if(basic_string<CharT, Traits, Allocator>& c, Pred 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>;
+
 
+
  // 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>;
+
  }
+
 
+
  // 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 {
+
    // suffix for basic_string literals
+
    constexpr string    operator""s(const char* str, size_t len);
+
    constexpr u8string  operator""s(const char8_t* str, size_t len);
+
    constexpr u16string operator""s(const char16_t* str, size_t len);
+
    constexpr u32string operator""s(const char32_t* str, size_t len);
+
    constexpr wstring  operator""s(const wchar_t* str, size_t len);
+
  }
+
  }
+
}
+
}}
+
 
+
====Class template {{lc|std::char_traits}}====
+
{{source|1=
+
namespace std {
+
  template<> struct char_traits<char> {
+
    using char_type  = char;
+
    using int_type  = int;
+
    using off_type  = streamoff;
+
    using pos_type  = streampos;
+
    using state_type = mbstate_t;
+
    using comparison_category = strong_ordering;
+
 
+
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
+
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
 
+
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
    static constexpr size_t length(const char_type* s);
+
    static constexpr const char_type* find(const char_type* s, size_t n,
+
                                          const char_type& a);
+
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
+
 
+
    static constexpr int_type not_eof(int_type c) noexcept;
+
    static constexpr char_type to_char_type(int_type c) noexcept;
+
    static constexpr int_type to_int_type(char_type c) noexcept;
+
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
+
    static constexpr int_type eof() noexcept;
+
  };
+
 
+
  template<> struct char_traits<char8_t> {
+
    using char_type  = char8_t;
+
    using int_type  = unsigned int;
+
    using off_type  = streamoff;
+
    using pos_type  = u8streampos;
+
    using state_type = mbstate_t;
+
    using comparison_category = strong_ordering;
+
 
+
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
+
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
 
+
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
    static constexpr size_t length(const char_type* s);
+
    static constexpr const char_type* find(const char_type* s, size_t n,
+
                                          const char_type& a);
+
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
+
    static constexpr int_type not_eof(int_type c) noexcept;
+
    static constexpr char_type to_char_type(int_type c) noexcept;
+
    static constexpr int_type to_int_type(char_type c) noexcept;
+
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
+
    static constexpr int_type eof() noexcept;
+
  };
+
 
+
  template<> struct char_traits<char16_t> {
+
    using char_type  = char16_t;
+
    using int_type  = uint_least16_t;
+
    using off_type  = streamoff;
+
    using pos_type  = u16streampos;
+
    using state_type = mbstate_t;
+
    using comparison_category = strong_ordering;
+
 
+
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
+
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
 
+
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
    static constexpr size_t length(const char_type* s);
+
    static constexpr const char_type* find(const char_type* s, size_t n,
+
                                          const char_type& a);
+
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
+
 
+
    static constexpr int_type not_eof(int_type c) noexcept;
+
    static constexpr char_type to_char_type(int_type c) noexcept;
+
    static constexpr int_type to_int_type(char_type c) noexcept;
+
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
+
    static constexpr int_type eof() noexcept;
+
  };
+
 
+
  template<> struct char_traits<char32_t> {
+
    using char_type  = char32_t;
+
    using int_type  = uint_least32_t;
+
    using off_type  = streamoff;
+
    using pos_type  = u32streampos;
+
    using state_type = mbstate_t;
+
    using comparison_category = strong_ordering;
+
 
+
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
+
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
 
+
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
    static constexpr size_t length(const char_type* s);
+
    static constexpr const char_type* find(const char_type* s, size_t n,
+
                                          const char_type& a);
+
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
+
 
+
    static constexpr int_type not_eof(int_type c) noexcept;
+
    static constexpr char_type to_char_type(int_type c) noexcept;
+
    static constexpr int_type to_int_type(char_type c) noexcept;
+
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
+
    static constexpr int_type eof() noexcept;
+
  };
+
 
+
  template<> struct char_traits<wchar_t> {
+
    using char_type  = wchar_t;
+
    using int_type  = wint_t;
+
    using off_type  = streamoff;
+
    using pos_type  = wstreampos;
+
    using state_type = mbstate_t;
+
    using comparison_category = strong_ordering;
+
 
+
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
+
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
 
+
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
+
    static constexpr size_t length(const char_type* s);
+
    static constexpr const char_type* find(const char_type* s, size_t n,
+
                                          const char_type& a);
+
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
+
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
+
 
+
    static constexpr int_type not_eof(int_type c) noexcept;
+
    static constexpr char_type to_char_type(int_type c) noexcept;
+
    static constexpr int_type to_int_type(char_type c) noexcept;
+
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
+
    static constexpr int_type eof() noexcept;
+
  };
+
}
+
}}
+
 
+
====Class template {{lc|std::basic_string}}====
+
{{source|1=
+
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 */;
+
    using const_iterator        = /* implementation-defined */;
+
    using reverse_iterator      = std::reverse_iterator<iterator>;
+
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
    static const size_type npos  = -1;
+
 
+
    // construct/copy/destroy
+
    constexpr basic_string() noexcept(noexcept(Allocator())) : basic_string(Allocator()) { }
+
    constexpr explicit basic_string(const Allocator& a) noexcept;
+
    constexpr basic_string(const basic_string& str);
+
    constexpr basic_string(basic_string&& str) noexcept;
+
    constexpr basic_string(const basic_string& str, size_type pos,
+
                          const Allocator& a = Allocator());
+
    constexpr basic_string(const basic_string& str, size_type pos, size_type n,
+
                          const Allocator& a = Allocator());
+
    template<class T>
+
      constexpr basic_string(const T& t, size_type pos, size_type n,
+
                            const Allocator& a = Allocator());
+
    template<class T>
+
      constexpr explicit basic_string(const T& t, const Allocator& a = Allocator());
+
    constexpr basic_string(const CharT* s, size_type n, const Allocator& a = Allocator());
+
    constexpr basic_string(const CharT* s, const Allocator& a = Allocator());
+
    constexpr basic_string(size_type n, CharT c, const Allocator& a = Allocator());
+
    template<class InputIt>
+
      constexpr basic_string(InputIt begin, InputIt end,
+
                            const Allocator& a = Allocator());
+
    constexpr basic_string(initializer_list<CharT>, const Allocator& = Allocator());
+
    constexpr basic_string(const basic_string&, const Allocator&);
+
    constexpr basic_string(basic_string&&, const Allocator&);
+
    constexpr ~basic_string();
+
 
+
    constexpr basic_string& operator=(const basic_string& str);
+
    constexpr 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>
+
      constexpr basic_string& operator=(const T& t);
+
    constexpr basic_string& operator=(const CharT* s);
+
    constexpr basic_string& operator=(CharT c);
+
    constexpr basic_string& operator=(initializer_list<CharT>);
+
 
+
    // iterators
+
    constexpr iterator      begin() noexcept;
+
    constexpr const_iterator begin() const noexcept;
+
    constexpr iterator      end() noexcept;
+
    constexpr const_iterator end() const noexcept;
+
 
+
    constexpr reverse_iterator      rbegin() noexcept;
+
    constexpr const_reverse_iterator rbegin() const noexcept;
+
    constexpr reverse_iterator      rend() noexcept;
+
    constexpr const_reverse_iterator rend() const noexcept;
+
 
+
    constexpr const_iterator        cbegin() const noexcept;
+
    constexpr const_iterator        cend() const noexcept;
+
    constexpr const_reverse_iterator crbegin() const noexcept;
+
    constexpr const_reverse_iterator crend() const noexcept;
+
 
+
    // capacity
+
    constexpr size_type size() const noexcept;
+
    constexpr size_type length() const noexcept;
+
    constexpr size_type max_size() const noexcept;
+
    constexpr void resize(size_type n, CharT c);
+
    constexpr void resize(size_type n);
+
    constexpr size_type capacity() const noexcept;
+
    constexpr void reserve(size_type res_arg);
+
    void reserve(); // deprecated
+
    constexpr void shrink_to_fit();
+
    constexpr void clear() noexcept;
+
    [[nodiscard]] constexpr bool empty() const noexcept;
+
 
+
    // element access
+
    constexpr const_reference operator[](size_type pos) const;
+
    constexpr reference      operator[](size_type pos);
+
    constexpr const_reference at(size_type n) const;
+
    constexpr reference      at(size_type n);
+
 
+
    constexpr const CharT& front() const;
+
    constexpr CharT&      front();
+
    constexpr const CharT& back() const;
+
    constexpr CharT&      back();
+
 
+
    // modifiers
+
    constexpr basic_string& operator+=(const basic_string& str);
+
    template<class T>
+
      constexpr basic_string& operator+=(const T& t);
+
    constexpr basic_string& operator+=(const CharT* s);
+
    constexpr basic_string& operator+=(CharT c);
+
    constexpr basic_string& operator+=(initializer_list<CharT>);
+
    constexpr basic_string& append(const basic_string& str);
+
    constexpr basic_string& append(const basic_string& str,
+
                                  size_type pos, size_type n = npos);
+
    template<class T>
+
      constexpr basic_string& append(const T& t);
+
    template<class T>
+
      constexpr basic_string& append(const T& t, size_type pos, size_type n = npos);
+
    constexpr basic_string& append(const CharT* s, size_type n);
+
    constexpr basic_string& append(const CharT* s);
+
    constexpr basic_string& append(size_type n, CharT c);
+
    template<class InputIt>
+
      constexpr basic_string& append(InputIt first, InputIt last);
+
    constexpr basic_string& append(initializer_list<CharT>);
+
 
+
    constexpr void push_back(CharT c);
+
 
+
    constexpr basic_string& assign(const basic_string& str);
+
    constexpr basic_string& assign(basic_string&& str)
+
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value {{!!}}
+
              allocator_traits<Allocator>::is_always_equal::value);
+
    constexpr basic_string& assign(const basic_string& str,
+
                                  size_type pos, size_type n = npos);
+
    template<class T>
+
      constexpr basic_string& assign(const T& t);
+
    template<class T>
+
      constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos);
+
    constexpr basic_string& assign(const CharT* s, size_type n);
+
    constexpr basic_string& assign(const CharT* s);
+
    constexpr basic_string& assign(size_type n, CharT c);
+
    template<class InputIt>
+
      constexpr basic_string& assign(InputIt first, InputIt last);
+
    constexpr basic_string& assign(initializer_list<CharT>);
+
 
+
    constexpr basic_string& insert(size_type pos, const basic_string& str);
+
    constexpr basic_string& insert(size_type pos1, const basic_string& str,
+
                                  size_type pos2, size_type n = npos);
+
    template<class T>
+
      constexpr basic_string& insert(size_type pos, const T& t);
+
    template<class T>
+
      constexpr basic_string& insert(size_type pos1, const T& t,
+
                                    size_type pos2, size_type n = npos);
+
    constexpr basic_string& insert(size_type pos, const CharT* s, size_type n);
+
    constexpr basic_string& insert(size_type pos, const CharT* s);
+
    constexpr basic_string& insert(size_type pos, size_type n, CharT c);
+
    constexpr iterator insert(const_iterator p, CharT c);
+
    constexpr iterator insert(const_iterator p, size_type n, CharT c);
+
    template<class InputIt>
+
      constexpr iterator insert(const_iterator p,
+
                                InputIt first, InputIt last);
+
    constexpr iterator insert(const_iterator p, initializer_list<CharT>);
+
 
+
    constexpr basic_string& erase(size_type pos = 0, size_type n = npos);
+
    constexpr iterator erase(const_iterator p);
+
    constexpr iterator erase(const_iterator first, const_iterator last);
+
 
+
    constexpr void pop_back();
+
 
+
    constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
+
    constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
+
                                    size_type pos2, size_type n2 = npos);
+
    template<class T>
+
      constexpr basic_string& replace(size_type pos1, size_type n1, const T& t);
+
    template<class T>
+
      constexpr basic_string& replace(size_type pos1, size_type n1, const T& t,
+
                                      size_type pos2, size_type n2 = npos);
+
    constexpr basic_string& replace(size_type pos, size_type n1, const CharT* s, size_type n2);
+
    constexpr basic_string& replace(size_type pos, size_type n1, const CharT* s);
+
    constexpr basic_string& replace(size_type pos, size_type n1, size_type n2, CharT c);
+
    constexpr basic_string& replace(const_iterator i1, const_iterator i2,
+
                                    const basic_string& str);
+
    template<class T>
+
      constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
+
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s,
+
                                    size_type n);
+
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s);
+
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n, CharT c);
+
    template<class InputIt>
+
      constexpr basic_string& replace(const_iterator i1, const_iterator i2,
+
                                      InputIt j1, InputIt j2);
+
    constexpr basic_string& replace(const_iterator, const_iterator, initializer_list<CharT>);
+
 
+
    constexpr size_type copy(CharT* s, size_type n, size_type pos = 0) const;
+
 
+
    constexpr void swap(basic_string& str)
+
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value {{!!}}
+
              allocator_traits<Allocator>::is_always_equal::value);
+
 
+
    // string operations
+
    constexpr const CharT* c_str() const noexcept;
+
    constexpr const CharT* data() const noexcept;
+
    constexpr CharT* data() noexcept;
+
    constexpr operator basic_string_view<CharT, Traits>() const noexcept;
+
    constexpr allocator_type get_allocator() const noexcept;
+
 
+
    template<class T>
+
      constexpr size_type find(const T& t, size_type pos = 0) const noexcept(/* see description */);
+
    constexpr size_type find(const basic_string& str, size_type pos = 0) const noexcept;
+
    constexpr size_type find(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type find(const CharT* s, size_type pos = 0) const;
+
    constexpr size_type find(CharT c, size_type pos = 0) const noexcept;
+
    template<class T>
+
      constexpr size_type rfind(const T& t, size_type pos = npos) const noexcept(/* see description */);
+
    constexpr size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
+
    constexpr size_type rfind(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type rfind(const CharT* s, size_type pos = npos) const;
+
    constexpr size_type rfind(CharT c, size_type pos = npos) const noexcept;
+
 
+
    template<class T>
+
      constexpr size_type find_first_of(const T& t, size_type pos = 0) const noexcept(/* see description */);
+
    constexpr size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
+
    constexpr size_type find_first_of(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type find_first_of(const CharT* s, size_type pos = 0) const;
+
    constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept;
+
    template<class T>
+
      constexpr size_type find_last_of(const T& t,
+
                                      size_type pos = npos) const noexcept(/* see description */);
+
    constexpr size_type find_last_of(const basic_string& str,
+
                                    size_type pos = npos) const noexcept;
+
    constexpr size_type find_last_of(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type find_last_of(const CharT* s, size_type pos = npos) const;
+
    constexpr size_type find_last_of(CharT c, size_type pos = npos) const noexcept;
+
 
+
    template<class T>
+
      constexpr size_type find_first_not_of(const T& t,
+
                                            size_type pos = 0) const noexcept(/* see description */);
+
    constexpr size_type find_first_not_of(const basic_string& str,
+
                                          size_type pos = 0) const noexcept;
+
    constexpr size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type find_first_not_of(const CharT* s, size_type pos = 0) const;
+
    constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const noexcept;
+
    template<class T>
+
      constexpr size_type find_last_not_of(const T& t,
+
                                          size_type pos = npos) const noexcept(/* see description */);
+
    constexpr size_type find_last_not_of(const basic_string& str,
+
                                        size_type pos = npos) const noexcept;
+
    constexpr size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const;
+
    constexpr size_type find_last_not_of(const CharT* s, size_type pos = npos) const;
+
    constexpr size_type find_last_not_of(CharT c, size_type pos = npos) const noexcept;
+
 
+
    constexpr basic_string substr(size_type pos = 0, size_type n = npos) const;
+
 
+
    template<class T>
+
      constexpr int compare(const T& t) const noexcept(/* see description */);
+
    template<class T>
+
      constexpr int compare(size_type pos1, size_type n1, const T& t) const;
+
    template<class T>
+
      constexpr int compare(size_type pos1, size_type n1, const T& t,
+
                            size_type pos2, size_type n2 = npos) const;
+
    constexpr int compare(const basic_string& str) const noexcept;
+
    constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const;
+
    constexpr int compare(size_type pos1, size_type n1, const basic_string& str,
+
                          size_type pos2, size_type n2 = npos) const;
+
    constexpr int compare(const CharT* s) const;
+
    constexpr int compare(size_type pos1, size_type n1, const CharT* s) const;
+
    constexpr int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const;
+
 
+
    constexpr bool starts_with(basic_string_view<CharT, Traits> x) const noexcept;
+
    constexpr bool starts_with(CharT x) const noexcept;
+
    constexpr bool starts_with(const CharT* x) const;
+
    constexpr bool ends_with(basic_string_view<CharT, Traits> x) const noexcept;
+
    constexpr bool ends_with(CharT x) const noexcept;
+
    constexpr bool ends_with(const CharT* x) const;
+
  };
+
 
+
  template<class InputIt,
+
          class Allocator = allocator<typename iterator_traits<InputIt>::value_type>>
+
    basic_string(InputIt, InputIt, Allocator = Allocator())
+
      -> basic_string<typename iterator_traits<InputIt>::value_type,
+
                      char_traits<typename iterator_traits<InputIt>::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,
+
===Defect reports===
          class Traits,
+
{{dr list begin}}
          class Allocator = allocator<CharT>>
+
{{dr list item|wg=lwg|dr=209|std=C++98|before=the declarations of the following {{lc|std::basic_string}}<br>members used inconsistent styles in the synopsis:
    basic_string(basic_string_view<CharT, Traits>,
+
* {{tt|void push_back(CharT c);}}
                typename /* see description */::size_type, typename /* see description */::size_type,
+
* {{tt|basic_string& assign(const basic_string& str);}}
                const Allocator& = Allocator())
+
* {{tt|void swap(basic_string& str);}}
      -> basic_string<CharT, Traits, Allocator>;
+
|after=uniformed the styles}}
}
+
{{dr list end}}
}}
+
  
{{langlinks|es|ja|zh}}
+
{{langlinks|es|ja|ru|zh}}

Latest revision as of 06:53, 27 November 2023

 
 
Standard library headers
Algorithms
<algorithm>
<numeric>
Strings
<cctype>
<cstring>
<cuchar> (C++11)
<cwchar>
<cwctype>
<string_view> (C++17)
<string>
Text processing
<clocale>
<codecvt> (C++11/17/26*)
<locale>
<regex> (C++11)
<text_encoding> (C++26)   
Numerics
<cfenv> (C++11)
<cmath>
<complex>
<linalg> (C++26)
<numbers> (C++20)
<random> (C++11)
<valarray>
Time
<chrono> (C++11)
<ctime>
C compatibility
<ccomplex> (C++11/17/20*)
<ciso646> (until C++20)
<cstdalign> (C++11/17/20*)
<cstdbool> (C++11/17/20*)
<ctgmath> (C++11/17/20*)
 

This header is part of the strings library.

Contents

Includes

(C++20)
Three-way comparison operator support[edit]
std::initializer_list class template[edit]

Classes

Class Template which describes properties of a character type
(class template)
std::char_traits<char> (class template specialization)
std::char_traits<wchar_t> (class template specialization)
std::char_traits<char8_t> (C++20) (class template specialization)
std::char_traits<char16_t> (C++11) (class template specialization)
std::char_traits<char32_t> (C++11) (class template specialization)
stores and manipulates sequences of characters
(class template) [edit]
std::string std::basic_string<char> (typedef)
std::u8string (C++20) std::basic_string<char8_t> (typedef)
std::u16string (C++11) std::basic_string<char16_t> (typedef)
std::u32string (C++11) std::basic_string<char32_t> (typedef)
std::wstring std::basic_string<wchar_t> (typedef)
std::pmr::basic_string (C++17) (alias template)
std::pmr::string (C++17) std::pmr::basic_string<char> (typedef)
std::pmr::u8string (C++20) std::pmr::basic_string<char8_t> (typedef)
std::pmr::u16string (C++17) std::pmr::basic_string<char16_t> (typedef)
std::pmr::u32string (C++17) std::pmr::basic_string<char32_t> (typedef)
std::pmr::wstring (C++17) std::pmr::basic_string<wchar_t> (typedef)
hash support for strings
(class template specialization)

Functions

concatenates two strings, a string and a char, or a string and string_view
(function template) [edit]
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20)
lexicographically compares two strings
(function template) [edit]
specializes the std::swap algorithm
(function template) [edit]
erases all elements satisfying specific criteria
(function template) [edit]
Input/output
performs stream input and output on strings
(function template) [edit]
read data from an I/O stream into a string
(function template) [edit]
Numeric conversions
(C++11)(C++11)(C++11)
converts a string to a signed integer
(function) [edit]
(C++11)(C++11)
converts a string to an unsigned integer
(function) [edit]
(C++11)(C++11)(C++11)
converts a string to a floating point value
(function) [edit]
(C++11)
converts an integral or floating-point value to string
(function) [edit]
converts an integral or floating-point value to wstring
(function) [edit]
Range access
(C++11)(C++14)
returns an iterator to the beginning of a container or array
(function template) [edit]
(C++11)(C++14)
returns an iterator to the end of a container or array
(function template) [edit]
returns a reverse iterator to the beginning of a container or array
(function template) [edit]
(C++14)
returns a reverse end iterator for a container or array
(function template) [edit]
(C++17)(C++20)
returns the size of a container or array
(function template) [edit]
(C++17)
checks whether the container is empty
(function template) [edit]
(C++17)
obtains the pointer to the underlying array
(function template) [edit]
Literals
Defined in inline namespace std::literals::string_literals
converts a character array literal to basic_string
(function) [edit]

[edit] Synopsis

#include <compare>
#include <initializer_list>
 
namespace std {
  // character traits
  template<class CharT> struct char_traits; // freestanding
  template<> struct char_traits<char>;      // freestanding
  template<> struct char_traits<char8_t>;   // freestanding
  template<> struct char_traits<char16_t>;  // freestanding
  template<> struct char_traits<char32_t>;  // freestanding
  template<> struct char_traits<wchar_t>;   // freestanding
 
  // basic_string
  template<class CharT, class Traits = char_traits<CharT>,
           class Allocator = allocator<CharT>>
    class basic_string;
 
  template<class CharT, class Traits, class Allocator>
    constexpr 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>
    constexpr 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>
    constexpr 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>
    constexpr 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>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(const CharT* lhs,
                const basic_string<CharT, Traits, Allocator>& rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(const CharT* lhs,
                basic_string<CharT, Traits, Allocator>&& rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(CharT lhs,
                const basic_string<CharT, Traits, Allocator>& rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(CharT lhs,
                basic_string<CharT, Traits, Allocator>&& rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(const basic_string<CharT, Traits, Allocator>& lhs,
                const CharT* rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(basic_string<CharT, Traits, Allocator>&& lhs,
                const CharT* rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(const basic_string<CharT, Traits, Allocator>& lhs,
                CharT rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(basic_string<CharT, Traits, Allocator>&& lhs,
                CharT rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(const basic_string<CharT, Traits, Allocator>& lhs,
                type_identity_t<basic_string_view<CharT, Traits>> rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(basic_string<CharT, Traits, Allocator>&& lhs,
                type_identity_t<basic_string_view<CharT, Traits>> rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(type_identity_t<basic_string_view<CharT, Traits>> lhs,
                const basic_string<CharT, Traits, Allocator>& rhs);
  template<class CharT, class Traits, class Allocator>
    constexpr basic_string<CharT, Traits, Allocator>
      operator+(type_identity_t<basic_string_view<CharT, Traits>> lhs,
                basic_string<CharT, Traits, Allocator>&& rhs);
 
  template<class CharT, class Traits, class Allocator>
    constexpr bool
      operator==(const basic_string<CharT, Traits, Allocator>& lhs,
                 const basic_string<CharT, Traits, Allocator>& rhs) noexcept;
  template<class CharT, class Traits, class Allocator>
    constexpr bool operator==(const basic_string<CharT, Traits, Allocator>& lhs,
                              const CharT* rhs);
 
  template<class CharT, class Traits, class Allocator>
    constexpr /* see description */ operator<=>(const basic_string<CharT,
                                                Traits, Allocator>& lhs,
                                                const basic_string<CharT,
                                                Traits, Allocator>& rhs) noexcept;
  template<class CharT, class Traits, class Allocator>
    constexpr /* see description */ operator<=>(const basic_string<CharT,
                                                Traits, Allocator>& lhs,
                                                const CharT* rhs);
 
  // swap
  template<class CharT, class Traits, class Allocator>
    constexpr void
      swap(basic_string<CharT, Traits, Allocator>& lhs,
           basic_string<CharT, Traits, Allocator>& rhs)
        noexcept(noexcept(lhs.swap(rhs)));
 
  // 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);
 
  // erasure
  template<class CharT, class Traits, class Allocator, class U = CharT>
    constexpr typename basic_string<CharT, Traits, Allocator>::size_type
      erase(basic_string<CharT, Traits, Allocator>& c, const U& value);
  template<class CharT, class Traits, class Allocator, class Pred>
    constexpr typename basic_string<CharT, Traits, Allocator>::size_type
      erase_if(basic_string<CharT, Traits, Allocator>& c, Pred 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>;
 
  // 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>;
  }
 
  // hash support
  template<class T> struct hash;
  template<class A> struct hash<basic_string<char, char_traits<char>, A>>;
  template<class A> struct hash<basic_string<char8_t, char_traits<char8_t>, A>>;
  template<class A> struct hash<basic_string<char16_t, char_traits<char16_t>, A>>;
  template<class A> struct hash<basic_string<char32_t, char_traits<char32_t>, A>>;
  template<class A> struct hash<basic_string<wchar_t, char_traits<wchar_t>, A>>;
 
  inline namespace literals {
  inline namespace string_literals {
    // suffix for basic_string literals
    constexpr string    operator""s(const char* str, size_t len);
    constexpr u8string  operator""s(const char8_t* str, size_t len);
    constexpr u16string operator""s(const char16_t* str, size_t len);
    constexpr u32string operator""s(const char32_t* str, size_t len);
    constexpr wstring   operator""s(const wchar_t* str, size_t len);
  }
  }
}

[edit] Class template std::char_traits

namespace std {
  template<> struct char_traits<char> {
    using char_type  = char;
    using int_type   = int;
    using off_type   = streamoff;
    using pos_type   = streampos;
    using state_type = mbstate_t;
    using comparison_category = strong_ordering;
 
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
 
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
 
    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
 
  template<> struct char_traits<char8_t> {
    using char_type  = char8_t;
    using int_type   = unsigned int;
    using off_type   = streamoff;
    using pos_type   = u8streampos;
    using state_type = mbstate_t;
    using comparison_category = strong_ordering;
 
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
 
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
 
  template<> struct char_traits<char16_t> {
    using char_type  = char16_t;
    using int_type   = uint_least16_t;
    using off_type   = streamoff;
    using pos_type   = u16streampos;
    using state_type = mbstate_t;
    using comparison_category = strong_ordering;
 
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
 
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
 
    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
 
  template<> struct char_traits<char32_t> {
    using char_type  = char32_t;
    using int_type   = uint_least32_t;
    using off_type   = streamoff;
    using pos_type   = u32streampos;
    using state_type = mbstate_t;
    using comparison_category = strong_ordering;
 
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
 
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
 
    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
 
  template<> struct char_traits<wchar_t> {
    using char_type  = wchar_t;
    using int_type   = wint_t;
    using off_type   = streamoff;
    using pos_type   = wstreampos;
    using state_type = mbstate_t;
    using comparison_category = strong_ordering;
 
    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;
 
    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static constexpr char_type* assign(char_type* s, size_t n, char_type a);
 
    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}

[edit] Class template std::basic_string

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 */;
    using const_iterator         = /* implementation-defined */;
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    static constexpr size_type npos = size_type(-1);
 
    // construct/copy/destroy
    constexpr basic_string() noexcept(noexcept(Allocator()))
      : basic_string(Allocator()) { }
    constexpr explicit basic_string(const Allocator& a) noexcept;
    constexpr basic_string(const basic_string& str);
    constexpr basic_string(basic_string&& str) noexcept;
    constexpr basic_string(const basic_string& str, size_type pos,
                           const Allocator& a = Allocator());
    constexpr basic_string(const basic_string& str, size_type pos, size_type n,
                           const Allocator& a = Allocator());
    constexpr basic_string(basic_string&& str, size_type pos,
                           const Allocator& a = Allocator());
    constexpr basic_string(basic_string&& str, size_type pos, size_type n,
                           const Allocator& a = Allocator());
    template<class T>
      constexpr basic_string(const T& t, size_type pos, size_type n,
                             const Allocator& a = Allocator());
    template<class T>
      constexpr explicit basic_string(const T& t, const Allocator& a = Allocator());
    constexpr basic_string(const CharT* s, size_type n, const Allocator& a = Allocator());
    constexpr basic_string(const CharT* s, const Allocator& a = Allocator());
    basic_string(nullptr_t) = delete;
    constexpr basic_string(size_type n, CharT c, const Allocator& a = Allocator());
    template<class InputIt>
      constexpr basic_string(InputIt begin, InputIt end,
                             const Allocator& a = Allocator());
    template<container-compatible-range<CharT> R>
      constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator());
    constexpr basic_string(initializer_list<CharT>, const Allocator& = Allocator());
    constexpr basic_string(const basic_string&, const Allocator&);
    constexpr basic_string(basic_string&&, const Allocator&);
    constexpr ~basic_string();
 
    constexpr basic_string& operator=(const basic_string& str);
    constexpr 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>
      constexpr basic_string& operator=(const T& t);
    constexpr basic_string& operator=(const CharT* s);
    basic_string& operator=(nullptr_t) = delete;
    constexpr basic_string& operator=(CharT c);
    constexpr basic_string& operator=(initializer_list<CharT>);
 
    // iterators
    constexpr iterator       begin() noexcept;
    constexpr const_iterator begin() const noexcept;
    constexpr iterator       end() noexcept;
    constexpr const_iterator end() const noexcept;
 
    constexpr reverse_iterator       rbegin() noexcept;
    constexpr const_reverse_iterator rbegin() const noexcept;
    constexpr reverse_iterator       rend() noexcept;
    constexpr const_reverse_iterator rend() const noexcept;
 
    constexpr const_iterator         cbegin() const noexcept;
    constexpr const_iterator         cend() const noexcept;
    constexpr const_reverse_iterator crbegin() const noexcept;
    constexpr const_reverse_iterator crend() const noexcept;
 
    // capacity
    constexpr size_type size() const noexcept;
    constexpr size_type length() const noexcept;
    constexpr size_type max_size() const noexcept;
    constexpr void resize(size_type n, CharT c);
    constexpr void resize(size_type n);
    template<class Operation>
      constexpr void resize_and_overwrite(size_type n, Operation op);
    constexpr size_type capacity() const noexcept;
    constexpr void reserve(size_type res_arg);
    constexpr void shrink_to_fit();
    constexpr void clear() noexcept;
    constexpr bool empty() const noexcept;
 
    // element access
    constexpr const_reference operator[](size_type pos) const;
    constexpr reference       operator[](size_type pos);
    constexpr const_reference at(size_type n) const;
    constexpr reference       at(size_type n);
 
    constexpr const CharT& front() const;
    constexpr CharT&       front();
    constexpr const CharT& back() const;
    constexpr CharT&       back();
 
    // modifiers
    constexpr basic_string& operator+=(const basic_string& str);
    template<class T>
      constexpr basic_string& operator+=(const T& t);
    constexpr basic_string& operator+=(const CharT* s);
    constexpr basic_string& operator+=(CharT c);
    constexpr basic_string& operator+=(initializer_list<CharT>);
    constexpr basic_string& append(const basic_string& str);
    constexpr basic_string& append(const basic_string& str, size_type pos,
                                   size_type n = npos);
    template<class T>
      constexpr basic_string& append(const T& t);
    template<class T>
      constexpr basic_string& append(const T& t, size_type pos, size_type n = npos);
    constexpr basic_string& append(const CharT* s, size_type n);
    constexpr basic_string& append(const CharT* s);
    constexpr basic_string& append(size_type n, CharT c);
    template<class InputIt>
      constexpr basic_string& append(InputIt first, InputIt last);
    template<container-compatible-range<CharT> R>
      constexpr basic_string& append_range(R&& rg);
    constexpr basic_string& append(initializer_list<CharT>);
 
    constexpr void push_back(CharT c);
 
    constexpr basic_string& assign(const basic_string& str);
    constexpr basic_string& assign(basic_string&& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
               allocator_traits<Allocator>::is_always_equal::value);
    constexpr basic_string& assign(const basic_string& str, size_type pos,
                                   size_type n = npos);
    template<class T>
      constexpr basic_string& assign(const T& t);
    template<class T>
      constexpr basic_string& assign(const T& t, size_type pos, size_type n = npos);
    constexpr basic_string& assign(const CharT* s, size_type n);
    constexpr basic_string& assign(const CharT* s);
    constexpr basic_string& assign(size_type n, CharT c);
    template<class InputIt>
      constexpr basic_string& assign(InputIt first, InputIt last);
    template<container-compatible-range<CharT> R>
      constexpr basic_string& assign_range(R&& rg);
    constexpr basic_string& assign(initializer_list<CharT>);
 
    constexpr basic_string& insert(size_type pos, const basic_string& str);
    constexpr basic_string& insert(size_type pos1, const basic_string& str,
                                   size_type pos2, size_type n = npos);
    template<class T>
      constexpr basic_string& insert(size_type pos, const T& t);
    template<class T>
      constexpr basic_string& insert(size_type pos1, const T& t,
                                     size_type pos2, size_type n = npos);
    constexpr basic_string& insert(size_type pos, const CharT* s, size_type n);
    constexpr basic_string& insert(size_type pos, const CharT* s);
    constexpr basic_string& insert(size_type pos, size_type n, CharT c);
    constexpr iterator insert(const_iterator p, CharT c);
    constexpr iterator insert(const_iterator p, size_type n, CharT c);
    template<class InputIt>
      constexpr iterator insert(const_iterator p, InputIt first, InputIt last);
    template<container-compatible-range<CharT> R>
      constexpr iterator insert_range(const_iterator p, R&& rg);
    constexpr iterator insert(const_iterator p, initializer_list<CharT>);
 
    constexpr basic_string& erase(size_type pos = 0, size_type n = npos);
    constexpr iterator erase(const_iterator p);
    constexpr iterator erase(const_iterator first, const_iterator last);
 
    constexpr void pop_back();
 
    constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
    constexpr basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                                    size_type pos2, size_type n2 = npos);
    template<class T>
      constexpr basic_string& replace(size_type pos1, size_type n1, const T& t);
    template<class T>
      constexpr basic_string& replace(size_type pos1, size_type n1, const T& t,
                                      size_type pos2, size_type n2 = npos);
    constexpr basic_string& replace(size_type pos, size_type n1, const CharT* s,
                                    size_type n2);
    constexpr basic_string& replace(size_type pos, size_type n1, const CharT* s);
    constexpr basic_string& replace(size_type pos, size_type n1, size_type n2, CharT c);
    constexpr basic_string& replace(const_iterator i1, const_iterator i2,
                                    const basic_string& str);
    template<class T>
      constexpr basic_string& replace(const_iterator i1, const_iterator i2, const T& t);
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s,
                                    size_type n);
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s);
    constexpr basic_string& replace(const_iterator i1, const_iterator i2, size_type n,
                                    CharT c);
    template<class InputIt>
      constexpr basic_string& replace(const_iterator i1, const_iterator i2,
                                      InputIt j1, InputIt j2);
    template<container-compatible-range<CharT> R>
      constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2,
                                                 R&& rg);
    constexpr basic_string& replace(const_iterator, const_iterator,
                                    initializer_list<CharT>);
 
    constexpr size_type copy(CharT* s, size_type n, size_type pos = 0) const;
 
    constexpr void swap(basic_string& str)
      noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
               allocator_traits<Allocator>::is_always_equal::value);
 
    // string operations
    constexpr const CharT* c_str() const noexcept;
    constexpr const CharT* data() const noexcept;
    constexpr CharT* data() noexcept;
    constexpr operator basic_string_view<CharT, Traits>() const noexcept;
    constexpr allocator_type get_allocator() const noexcept;
 
    template<class T>
      constexpr size_type find(const T& t,
                               size_type pos = 0) const noexcept(/* see description */);
    constexpr size_type find(const basic_string& str, size_type pos = 0) const noexcept;
    constexpr size_type find(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type find(const CharT* s, size_type pos = 0) const;
    constexpr size_type find(CharT c, size_type pos = 0) const noexcept;
    template<class T>
      constexpr size_type rfind(const T& t, size_type pos = npos)
        const noexcept(/* see description */);
    constexpr size_type rfind(const basic_string& str,
                              size_type pos = npos) const noexcept;
    constexpr size_type rfind(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type rfind(const CharT* s, size_type pos = npos) const;
    constexpr size_type rfind(CharT c, size_type pos = npos) const noexcept;
 
    template<class T>
      constexpr size_type find_first_of(const T& t, size_type pos = 0)
        const noexcept(/* see description */);
    constexpr size_type find_first_of(const basic_string& str,
                                      size_type pos = 0) const noexcept;
    constexpr size_type find_first_of(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type find_first_of(const CharT* s, size_type pos = 0) const;
    constexpr size_type find_first_of(CharT c, size_type pos = 0) const noexcept;
    template<class T>
      constexpr size_type find_last_of(const T& t, size_type pos = npos)
        const noexcept(/* see description */);
    constexpr size_type find_last_of(const basic_string& str,
                                     size_type pos = npos) const noexcept;
    constexpr size_type find_last_of(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type find_last_of(const CharT* s, size_type pos = npos) const;
    constexpr size_type find_last_of(CharT c, size_type pos = npos) const noexcept;
 
    template<class T>
      constexpr size_type find_first_not_of(const T& t, size_type pos = 0)
        const noexcept(/* see description */);
    constexpr size_type find_first_not_of(const basic_string& str,
                                          size_type pos = 0) const noexcept;
    constexpr size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type find_first_not_of(const CharT* s, size_type pos = 0) const;
    constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const noexcept;
    template<class T>
      constexpr size_type find_last_not_of(const T& t, size_type pos = npos)
        const noexcept(/* see description */);
    constexpr size_type find_last_not_of(const basic_string& str,
                                         size_type pos = npos) const noexcept;
    constexpr size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const;
    constexpr size_type find_last_not_of(const CharT* s, size_type pos = npos) const;
    constexpr size_type find_last_not_of(CharT c, size_type pos = npos) const noexcept;
 
    constexpr basic_string substr(size_type pos = 0, size_type n = npos) const &;
    constexpr basic_string substr(size_type pos = 0, size_type n = npos) &&;
 
    template<class T>
      constexpr int compare(const T& t) const noexcept(/* see description */);
    template<class T>
      constexpr int compare(size_type pos1, size_type n1, const T& t) const;
    template<class T>
      constexpr int compare(size_type pos1, size_type n1, const T& t,
                            size_type pos2, size_type n2 = npos) const;
    constexpr int compare(const basic_string& str) const noexcept;
    constexpr int compare(size_type pos1, size_type n1, const basic_string& str) const;
    constexpr int compare(size_type pos1, size_type n1, const basic_string& str,
                          size_type pos2, size_type n2 = npos) const;
    constexpr int compare(const CharT* s) const;
    constexpr int compare(size_type pos1, size_type n1, const CharT* s) const;
    constexpr int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const;
 
    constexpr bool starts_with(basic_string_view<CharT, Traits> x) const noexcept;
    constexpr bool starts_with(CharT x) const noexcept;
    constexpr bool starts_with(const CharT* x) const;
    constexpr bool ends_with(basic_string_view<CharT, Traits> x) const noexcept;
    constexpr bool ends_with(CharT x) const noexcept;
    constexpr bool ends_with(const CharT* x) const;
 
    constexpr bool contains(basic_string_view<CharT, Traits> x) const noexcept;
    constexpr bool contains(CharT x) const noexcept;
    constexpr bool contains(const CharT* x) const;
  };
 
  template<class InputIt,
           class Allocator = allocator<typename iterator_traits<InputIt>::value_type>>
    basic_string(InputIt, InputIt, Allocator = Allocator())
      -> basic_string<typename iterator_traits<InputIt>::value_type,
                      char_traits<typename iterator_traits<InputIt>::value_type>,
                      Allocator>;
 
  template<ranges::input_range R,
           class Allocator = allocator<ranges::range_value_t<R>>>
    basic_string(from_range_t, R&&, Allocator = Allocator())
      -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>,
                      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 description */::size_type,
                 typename /* see description */::size_type,
                 const Allocator& = Allocator())
      -> basic_string<CharT, Traits, Allocator>;
}

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 209 C++98 the declarations of the following std::basic_string
members used inconsistent styles in the synopsis:
  • void push_back(CharT c);
  • basic_string& assign(const basic_string& str);
  • void swap(basic_string& str);
uniformed the styles