[string.nonmembers] # 27 Strings library [[strings]](./#strings) ## 27.4 String classes [[string.classes]](string.classes#string.nonmembers) ### 27.4.4 Non-member functions [string.nonmembers] #### [27.4.4.1](#string.op.plus) operator+ [[string.op.plus]](string.op.plus) [🔗](#lib:operator+,basic_string) `template constexpr basic_string operator+(const basic_string& lhs, const basic_string& rhs); template constexpr basic_string operator+(const basic_string& lhs, const charT* rhs); ` [1](#string.op.plus-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4719) *Effects*: Equivalent to:basic_string r = lhs; r.append(rhs);return r; [🔗](#lib:operator+,basic_string_) `template constexpr basic_string operator+(basic_string&& lhs, const basic_string& rhs); template constexpr basic_string operator+(basic_string&& lhs, const charT* rhs); ` [2](#string.op.plus-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4741) *Effects*: Equivalent to:lhs.append(rhs);return std::move(lhs); [🔗](#lib:operator+,basic_string__) `template constexpr basic_string operator+(basic_string&& lhs, basic_string&& rhs); ` [3](#string.op.plus-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4759) *Effects*: Equivalent to:lhs.append(rhs);return std::move(lhs); except that both lhs and rhs are left in valid but unspecified states[.](#string.op.plus-3.sentence-1) [*Note [1](#string.op.plus-note-1)*: If lhs and rhs have equal allocators, the implementation can move from either[.](#string.op.plus-3.sentence-2) — *end note*] [🔗](#lib:operator+,basic_string___) `template constexpr basic_string operator+(const basic_string& lhs, basic_string&& rhs); template constexpr basic_string operator+(const charT* lhs, basic_string&& rhs); ` [4](#string.op.plus-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4786) *Effects*: Equivalent to:rhs.insert(0, lhs);return std::move(rhs); [🔗](#lib:operator+,basic_string____) `template constexpr basic_string operator+(const charT* lhs, const basic_string& rhs); ` [5](#string.op.plus-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4803) *Effects*: Equivalent to:basic_string r = rhs; r.insert(0, lhs);return r; [🔗](#lib:operator+,basic_string_____) `template constexpr basic_string operator+(charT lhs, const basic_string& rhs); ` [6](#string.op.plus-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4821) *Effects*: Equivalent to:basic_string r = rhs; r.insert(r.begin(), lhs);return r; [🔗](#lib:operator+,basic_string______) `template constexpr basic_string operator+(charT lhs, basic_string&& rhs); ` [7](#string.op.plus-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4839) *Effects*: Equivalent to:rhs.insert(rhs.begin(), lhs);return std::move(rhs); [🔗](#lib:operator+,basic_string_______) `template constexpr basic_string operator+(const basic_string& lhs, charT rhs); ` [8](#string.op.plus-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4856) *Effects*: Equivalent to:basic_string r = lhs; r.push_back(rhs);return r; [🔗](#lib:operator+,basic_string________) `template constexpr basic_string operator+(basic_string&& lhs, charT rhs); ` [9](#string.op.plus-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4874) *Effects*: Equivalent to:lhs.push_back(rhs);return std::move(lhs); [🔗](#lib:operator+,basic_string_________) `template constexpr basic_string operator+(const basic_string& lhs, type_identity_t> rhs); ` [10](#string.op.plus-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4892) Equivalent to:basic_string r = lhs; r.append(rhs);return r; [🔗](#lib:operator+,basic_string__________) `template constexpr basic_string operator+(basic_string&& lhs, type_identity_t> rhs); ` [11](#string.op.plus-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4910) Equivalent to:lhs.append(rhs);return std::move(lhs); [🔗](#lib:operator+,basic_string___________) `template constexpr basic_string operator+(type_identity_t> lhs, const basic_string& rhs); ` [12](#string.op.plus-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4927) Equivalent to:basic_string r = rhs; r.insert(0, lhs);return r; [🔗](#lib:operator+,basic_string____________) `template constexpr basic_string operator+(type_identity_t> lhs, basic_string&& rhs); ` [13](#string.op.plus-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4945) Equivalent to:rhs.insert(0, lhs);return std::move(rhs); [14](#string.op.plus-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4953) [*Note [2](#string.op.plus-note-2)*: Using a specialization of type_identity_t as a parameter type ensures that an object of type basic_string can be concatenated with an object of a type T having an implicit conversion tobasic_string_view ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"))[.](#string.op.plus-14.sentence-1) — *end note*] #### [27.4.4.2](#string.cmp) Non-member comparison operator functions [[string.cmp]](string.cmp) [🔗](#string.cmp-itemdecl:1) `template constexpr bool operator==(const basic_string& lhs, const basic_string& rhs) noexcept; template constexpr bool operator==(const basic_string& lhs, const charT* rhs); template constexpr see below operator<=>(const basic_string& lhs, const basic_string& rhs) noexcept; template constexpr see below operator<=>(const basic_string& lhs, const charT* rhs); ` [1](#string.cmp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4980) *Effects*: Let *op* be the operator[.](#string.cmp-1.sentence-1) Equivalent to:return basic_string_view(lhs) *op* basic_string_view(rhs); #### [27.4.4.3](#string.special) swap [[string.special]](string.special) [🔗](#lib:swap,basic_string) `template constexpr void swap(basic_string& lhs, basic_string& rhs) noexcept(noexcept(lhs.swap(rhs))); ` [1](#string.special-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5001) *Effects*: Equivalent to lhs.swap(rhs)[.](#string.special-1.sentence-1) #### [27.4.4.4](#string.io) Inserters and extractors [[string.io]](string.io) [🔗](#lib:operator%3e%3e,basic_string) `template basic_istream& operator>>(basic_istream& is, basic_string& str); ` [1](#string.io-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5016) *Effects*: Behaves as a formatted input function ([[istream.formatted.reqmts]](istream.formatted.reqmts "31.7.5.3.1 Common requirements"))[.](#string.io-1.sentence-1) After constructing a sentry object, if the sentry object returns true when converted to a value of type bool, calls str.erase() and then extracts characters from is and appends them to str as if by callingstr.append(1, c)[.](#string.io-1.sentence-2) Ifis.width() is greater than zero, the maximum number n of characters appended isis.width(); otherwise n isstr.max_size()[.](#string.io-1.sentence-3) Characters are extracted and appended until any of the following occurs: - [(1.1)](#string.io-1.1) *n* characters are stored; - [(1.2)](#string.io-1.2) end-of-file occurs on the input sequence; - [(1.3)](#string.io-1.3) isspace(c, is.getloc()) is true for the next available input character*c*[.](#string.io-1.sentence-4) [2](#string.io-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5047) After the last character (if any) is extracted,is.width(0) is called and thesentry object is destroyed[.](#string.io-2.sentence-1) [3](#string.io-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5054) If the function extracts no characters,ios_base​::​failbit is set in the input function's local error state before setstate is called[.](#string.io-3.sentence-1) [4](#string.io-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5059) *Returns*: is[.](#string.io-4.sentence-1) [🔗](#lib:operator%3c%3c,basic_string) `template basic_ostream& operator<<(basic_ostream& os, const basic_string& str); ` [5](#string.io-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5073) *Effects*: Equivalent to: return os << basic_string_view(str); [🔗](#lib:getline,basic_string) `template basic_istream& getline(basic_istream& is, basic_string& str, charT delim); template basic_istream& getline(basic_istream&& is, basic_string& str, charT delim); ` [6](#string.io-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5093) *Effects*: Behaves as an unformatted input function ([[istream.unformatted]](istream.unformatted "31.7.5.4 Unformatted input functions")), except that it does not affect the value returned by subsequent calls tobasic_istream<>​::​gcount()[.](#string.io-6.sentence-1) After constructing a sentry object, if the sentry object returns true when converted to a value of type bool, calls str.erase() and then extracts characters from is and appends them to str as if by callingstr.append(1, c) until any of the following occurs: - [(6.1)](#string.io-6.1) end-of-file occurs on the input sequence; - [(6.2)](#string.io-6.2) traits​::​eq(c, delim) for the next available input character*c* (in which case,*c* is extracted but not appended); - [(6.3)](#string.io-6.3) str.max_size() characters are stored (in which case,ios_base​::​failbit is set in the input function's local error state)[.](#string.io-6.sentence-2) [7](#string.io-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5123) The conditions are tested in the order shown[.](#string.io-7.sentence-1) In any case, after the last character is extracted, thesentry object is destroyed[.](#string.io-7.sentence-2) [8](#string.io-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5130) If the function extracts no characters,ios_base​::​failbit is set in the input function's local error state before setstate is called[.](#string.io-8.sentence-1) [9](#string.io-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5135) *Returns*: is[.](#string.io-9.sentence-1) [🔗](#lib:getline,basic_string_) `template basic_istream& getline(basic_istream& is, basic_string& str); template basic_istream& getline(basic_istream&& is, basic_string& str); ` [10](#string.io-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5153) *Returns*: getline(is, str, is.widen('\n'))[.](#string.io-10.sentence-1) #### [27.4.4.5](#string.erasure) Erasure [[string.erasure]](string.erasure) [🔗](#lib:erase,basic_string) `template constexpr typename basic_string::size_type erase(basic_string& c, const U& value); ` [1](#string.erasure-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5168) *Effects*: Equivalent to:auto it = remove(c.begin(), c.end(), value);auto r = distance(it, c.end()); c.erase(it, c.end());return r; [🔗](#lib:erase_if,basic_string) `template constexpr typename basic_string::size_type erase_if(basic_string& c, Predicate pred); ` [2](#string.erasure-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L5187) *Effects*: Equivalent to:auto it = remove_if(c.begin(), c.end(), pred);auto r = distance(it, c.end()); c.erase(it, c.end());return r;