# std::operator+(std::basic_string)

< cpp‎ | string‎ | basic string

定义于头文件 `<string>` |  |
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( const std::basic_string<CharT,Traits,Alloc>& lhs, const std::basic_string<CharT,Traits,Alloc>& rhs ); | (1) | (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( const std::basic_string<CharT,Traits,Alloc>& lhs, const CharT* rhs ); | (2) | (C++20 起为 `constexpr`)
template<class CharT, class Traits, class Alloc> std::basic_string<CharT,Traits,Alloc> operator+( const std::basic_string<CharT,Traits,Alloc>& lhs, CharT rhs ); | (3) | (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( const CharT* lhs, const std::basic_string<CharT,Traits,Alloc>& rhs ); | (4) | (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( CharT lhs, const std::basic_string<CharT,Traits,Alloc>& rhs ); | (5) | (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( std::basic_string<CharT,Traits,Alloc>&& lhs, std::basic_string<CharT,Traits,Alloc>&& rhs ); | (6) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( std::basic_string<CharT,Traits,Alloc>&& lhs, const std::basic_string<CharT,Traits,Alloc>& rhs ); | (7) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( std::basic_string<CharT,Traits,Alloc>&& lhs, const CharT* rhs ); | (8) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( std::basic_string<CharT,Traits,Alloc>&& lhs, CharT rhs ); | (9) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( const std::basic_string<CharT,Traits,Alloc>& lhs, std::basic_string<CharT,Traits,Alloc>&& rhs ); | (10) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( const CharT* lhs, std::basic_string<CharT,Traits,Alloc>&& rhs ); | (11) | (C++11 起) (C++20 起为 `constexpr`)
template< class CharT, class Traits, class Alloc > std::basic_string<CharT,Traits,Alloc> operator+( CharT lhs, std::basic_string<CharT,Traits,Alloc>&& rhs ); | (12) | (C++11 起) (C++20 起为 `constexpr`)

返回含有来自 `lhs` 的字符后随来自 `rhs` 的字符的字符串。

结果所用的分配器为： 1-3) std::allocator_traits<Alloc>::select_on_container_copy_construction(lhs.get_allocator()) 4-5) std::allocator_traits<Alloc>::select_on_container_copy_construction(rhs.get_allocator()) 6-9) lhs.get_allocator() 10-12) rhs.get_allocator() 换言之，若运算数之一是 `basic_string` 右值，则使用其分配器；否则在左值 `basic_string` 运算数的分配上使用 `select_on_container_copy_construction` 。每种情况下，当两者是拥有同一值类别的 `basic_string` 时，偏向左运算数。 (6-12) 将所有右值 `basic_string` 运算数置于合法但未指定的状态。 | (C++11 起)

### 参数

lhs | - | `string` 、字符或指向空终止字符序列首字符的指针
rhs | - | `string` 、字符或指向空终止字符序列首字符的指针

### 返回值

含有来自 `lhs` 的字符后随来自 `rhs` 的字符的字符串，使用指定如上的分配器 (C++11 起)。

### 注解 涉及有状态分配器时（例如用 std::pmr::string 时） (C++17 起)，应该谨慎使用 `operator+` 。在 P1165R1 前，确定结果所用的分配器是历史事故，而且能在重载间无显著理由地变化。另外，对于 (1-5) ，分配器传播行为在主流标准库实现间各异，且异于标准所描述的行为。 `operator+` 的结果所用的分配器对值类别敏感，故 `operator+` 相对于分配器传播不满足结合律：
    using my_string = std::basic_string<char, std::char_traits<char>, my_allocator<char>>;
    my_string cat();
    const my_string& dog();

    my_string meow = /* ... */, woof = /* ... */;
    meow + cat() + /*...*/; // 使用 meow 的分配器上的 select_on_container_copy_construction
    woof + dog() + /*...*/; // 转而使用 dog() 的返回值的分配器

    meow + woof + meow; // 使用 meow 的分配器上的 SOCCC
    meow + (woof + meow); // 转而使用 woof 的分配器上的 select_on_container_copy_construction
对于 `operator+` 链的调用，可通过前置拥有所欲分配器的右值 `basic_string` 控制最终结果所用的分配器：
    // 令最终结果使用 my_favorite_allocator
    my_string(my_favorite_allocator) + meow + woof + cat() + dog();
为了在分配器上更好且可移植地控制，应该在以所欲分配器构造的结果字符串上，使用 `append()` 、 `insert()` 及 `operator+=()` 之类的成员函数。 | (C++11 起)

### 示例

    #include <iostream>
    #include <string>

    int main()
    {
        std::string s1 = "Hello";
        std::string s2 = "world";
        std::cout << s1 + ' ' + s2 + "!\n";
    }

输出：

    Hello world!

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
P1165R1 | C++11 | 分配器传播混乱且不一致 | 使之更为一致

### 参阅

operator+= | 后附字符到结尾 (公开成员函数)
append | 后附字符到结尾 (公开成员函数)
insert | 插入字符 (公开成员函数)