[string.op.plus]

# 27 Strings library [[strings]](./#strings)

## 27.4 String classes [[string.classes]](string.classes#string.op.plus)

### 27.4.4 Non-member functions [[string.nonmembers]](string.nonmembers#string.op.plus)

#### 27.4.4.1 operator+ [string.op.plus]

[ð](#lib:operator+,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+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4719)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.append(rhs);return r;

[ð](#lib:operator+,basic_string_)

`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+(basic_string<charT, traits, Allocator>&& lhs, const charT* rhs);
`

[2](#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<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);
`

[3](#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[.](#3.sentence-1)

[*Note [1](#note-1)*:

If lhs and rhs have equal allocators,
the implementation can move from either[.](#3.sentence-2)

â *end note*]

[ð](#lib:operator+,basic_string___)

`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+(const charT* lhs, basic_string<charT, traits, Allocator>&& rhs);
`

[4](#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<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs);
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4803)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(0, lhs);return r;

[ð](#lib:operator+,basic_string_____)

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

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4821)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(r.begin(), lhs);return r;

[ð](#lib:operator+,basic_string______)

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

[7](#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<class charT, class traits, class Allocator>
  constexpr basic_string<charT, traits, Allocator>
    operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4856)

*Effects*: Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.push_back(rhs);return r;

[ð](#lib:operator+,basic_string________)

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

[9](#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<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);
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4892)

Equivalent to:basic_string<charT, traits, Allocator> r = lhs;
r.append(rhs);return r;

[ð](#lib:operator+,basic_string__________)

`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);
`

[11](#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<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);
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4927)

Equivalent to:basic_string<charT, traits, Allocator> r = rhs;
r.insert(0, lhs);return r;

[ð](#lib:operator+,basic_string____________)

`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);
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4945)

Equivalent to:rhs.insert(0, lhs);return std::move(rhs);

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/strings.tex#L4953)

[*Note [2](#note-2)*:

Using a specialization of type_identity_t as a parameter type ensures
that an object of type basic_string<charT, traits, Allocator> can be concatenated with an object of a type T having an implicit conversion tobasic_string_view<charT, traits> ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"))[.](#14.sentence-1)

â *end note*]
