std::operator+(std::basic_string)

来自cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
 
在标头 <string> 定义
template<class CharT, class Traits, class Alloc >

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

               conststd::basic_string<CharT,Traits,Alloc>& rhs );
(1) (C++20 起为 constexpr)
template<class CharT, class Traits, class Alloc >

std::basic_string<CharT,Traits,Alloc>
    operator+(conststd::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+(conststd::basic_string<CharT,Traits,Alloc>& lhs,

               CharT rhs );
(3) (C++20 起为 constexpr)
template<class CharT, class Traits, class Alloc >

constexprstd::basic_string<CharT,Traits,Alloc>
    operator+(conststd::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,

               conststd::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,

               conststd::basic_string<CharT,Traits,Alloc>& rhs );
(6) (C++20 起为 constexpr)
template<class CharT, class Traits, class Alloc >

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

               conststd::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,

               conststd::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 >

constexprstd::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+(conststd::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 >

constexprstd::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 右值,则使用其分配器。
  • 否则在左值 basic_string 操作数的分配上使用 select_on_container_copy_construction

每种情况下,当两者是拥有同一值类别的 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()+/*...*/;// 使用 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 起)

根据重载决议规则,使用 std::type_identity_t 作为重载 (4)(7)(12)(16) 的形参,保证了 std::basic_string<CharT, Traits, Allocator> 类型的对象总是可以与能够隐式转换为 std::basic_string_view<CharT, Traits>T 类型的对象进行连接,反之亦然。

功能特性测试标准功能特性
__cpp_lib_string_view202403(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";constchar* end ="!\n";std::cout<< s1 +' '+ s2 + end;   std::string_view water{" Water"};#if __cpp_lib_string_view >= 202403std::cout<< s1 + water + s2 << end;// 重载 (4),然后重载 (1)#elsestd::cout<< s1 +std::string(water)+ s2 << end;// OK,但较低效#endif}

输出:

Hello world! Hello Waterworld!

[编辑]缺陷报告

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

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

[编辑]参阅

后附字符到结尾
(公开成员函数)[编辑]
后附字符到结尾
(公开成员函数)[编辑]
插入字符
(公开成员函数)[编辑]
close