命名空间
变体
操作

std::operator+(std::basic_string)

来自 cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
成员函数
元素访问
迭代器
容量
修改器
搜索
操作
常量
非成员函数
operator+
I/O
比较
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20)
数字转换
(C++11)(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
字面量
辅助类
推导指南 (C++17)

 
在头文件 <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 >

constexpr std::basic_string<CharT,Traits,Alloc>
    operator+( const std::basic_string<CharT,Traits,Alloc>& lhs,

               std::type_identity_t<std::basic_string_view<CharT,Traits>> rhs );
(4) (从 C++26 开始)
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 );
(5) (从 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 );
(6) (从 C++20 开始为 constexpr)
template< class CharT, class Traits, class Alloc >

constexpr std::basic_string<CharT,Traits,Alloc>
    operator+( std::type_identity_t<std::basic_string_view<CharT,Traits>> lhs,

               const std::basic_string<CharT,Traits,Alloc>& rhs );
(7) (从 C++26 开始)
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 );
(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,

               const std::basic_string<CharT,Traits,Alloc>& rhs );
(9) (从 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 );
(10) (从 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 );
(11) (从 C++11 开始)
(从 C++20 开始为 constexpr)
template< class CharT, class Traits, class Alloc >

constexpr std::basic_string<CharT,Traits,Alloc>
    operator+( std::basic_string<CharT,Traits,Alloc>&& lhs,

               std::type_identity_t<std::basic_string_view<CharT,Traits>> rhs );
(12) (从 C++26 开始)
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 );
(13) (从 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 );
(14) (从 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 );
(15) (从 C++11 开始)
(从 C++20 开始为 constexpr)
template< class CharT, class Traits, class Alloc >

constexpr std::basic_string<CharT,Traits,Alloc>
    operator+( std::type_identity_t<std::basic_string_view<CharT,Traits>> lhs,

               std::basic_string<CharT,Traits,Alloc>&& rhs );
(16) (从 C++26 开始)

返回一个字符串,其中包含来自 lhs 的字符,后面跟着来自 rhs 的字符。等效于

1,2) std::basic_string<CharT, Traits, Allocator> r = lhs; r.append(rhs); return r;
3) std::basic_string<CharT, Traits, Allocator> r = lhs; r.push_back(rhs); return r;
4) std::basic_string<CharT, Traits, Allocator> r = lhs; r.append(rhs); return r;
5) std::basic_string<CharT, Traits, Allocator> r = rhs; r.insert(0, lhs); return r;
6) std::basic_string<CharT, Traits, Allocator> r = rhs; r.insert(r.begin(), lhs); return r;
7) std::basic_string<CharT, Traits, Allocator> r = rhs; r.insert(0, lhs); return r;
8) lhs.append(rhs); return std::move(lhs); 除了 lhsrhs 都处于有效但未指定的狀態外。如果 lhsrhs 具有相同的分配器,則實作可以從任一者移動。
9,10) lhs.append(rhs); return std::move(lhs);
11) lhs.push_back(rhs); return std::move(lhs);
12) lhs.append(rhs); return std::move(lhs);
13,14) rhs.insert(0, lhs); return std::move(rhs);
15) rhs.insert(rhs.begin(), lhs); return std::move(rhs);
16) rhs.insert(0, lhs); return std::move(rhs);

使用的分配器是

1-4) std::allocator_traits<Alloc>::select_on_container_copy_construction(lhs.get_allocator())
5-7) std::allocator_traits<Alloc>::select_on_container_copy_construction(rhs.get_allocator())
8-12) lhs.get_allocator()
13-16) rhs.get_allocator()

换句话说

  • 如果一个操作数是 basic_string 右值,则使用其分配器。
  • 否则,将 select_on_container_copy_construction 用于左值 basic_string 操作数的分配器。

在每种情况下,当两个操作数都是相同值类别的 basic_string 时,优先使用左操作数。

对于 (8-16),所有右值 basic_string 操作数都处于有效但未指定的狀態。

(从 C++11 开始)

内容

[编辑] 参数

lhs - 字符串,字符串视图(自 C++26 起),字符或指向空终止数组中第一个字符的指针
rhs - 字符串,字符串视图(自 C++26 起),字符或指向空终止数组中第一个字符的指针

[编辑] 返回值

包含来自 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() + /* ... */; // uses select_on_container_copy_construction on meow's allocator
woof + dog() + /* ... */; // uses allocator of dog()'s return value instead
 
meow + woof + meow; // uses select_on_container_copy_construction on meow's allocator
meow + (woof + meow); // uses SOCCC on woof's allocator instead

对于 operator+ 调用链,最终结果使用的分配器可以通过使用具有所需分配器的右值 basic_string 作为前缀来控制

// use my_favorite_allocator for the final result
my_string(my_favorite_allocator) + meow + woof + cat() + dog();

为了更好地控制分配器并具有可移植性,应在使用所需分配器构建的结果字符串上使用 appendinsertoperator+= 等成员函数。

(从 C++11 开始)

在过载 (4)(7)(12)(16) 中使用 std::type_identity_t 作为参数可确保类型为 std::basic_string<CharT, Traits, Allocator> 的对象始终可以与类型为 T 的对象连接,该对象具有隐式转换为 std::basic_string_view<CharT, Traits>,反之亦然,根据 过载解析 规则。

功能测试 Std 功能
__cpp_lib_string_view 202403 (C++26) 字符串和字符串视图的连接,过载 (4)(7)(12)(16)
(从 C++26 开始)

[编辑] 示例

#include <iostream>
#include <string>
#include <string_view>
 
int main()
{
    std::string s1 = "Hello";
    std::string s2 = "world";
    const char* end = "!\n";
    std::cout << s1 + ' ' + s2 + end;
 
    std::string_view water{" Water"};
    #if __cpp_lib_string_view >= 202403
    std::cout << s1 + water + s2 << end; // overload (4), then (1)
    #else
    std::cout << s1 + std::string(water) + s2 << end; // OK, but less efficient
    #endif
}

输出

Hello world!
Hello Waterworld!

[编辑] 缺陷报告

以下行为更改缺陷报告已追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
P1165R1 C++11 分配器传播是混乱且不一致的 更一致

[编辑] 参见

将字符追加到末尾
(公共成员函数) [编辑]
将字符追加到末尾
(公共成员函数) [编辑]
插入字符
(公共成员函数) [编辑]