Namespaces
Variants

std:: operator+ (std::basic_string)

From zh.cppreference.net
std::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 >

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 ) ; 不同之处在于 lhs 和 rhs 均处于有效但未指定的状态。如果 lhs 与 rhs 具有相等的分配器,实现可以选择移动任意一方的资源。
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 - string , string view (since C++26) , character, or pointer to the first character in a null-terminated array
rhs - string , string view (since C++26) , character, or pointer to the first character in a null-terminated array

返回值

一个包含来自 lhs 的字符,后接来自 rhs 的字符所组成的字符串 ,使用如上确定的分配器 (C++11 起) 。

注解

operator+ 在涉及有状态分配器时应极其谨慎地使用 (例如使用 std::pmr::string 时) (C++17 起) 。在 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 的分配器使用 select_on_container_copy_construction
meow + (woof + meow); // 改为对 woof 的分配器使用 SOCCC

对于连续的 operator+ 调用链,可通过前置一个具有所需分配器的右值 basic_string 来控制最终结果使用的分配器:

// 为最终结果使用 my_favorite_allocator
my_string(my_favorite_allocator) + meow + woof + cat() + dog();

为实现更好且可移植的分配器控制,应在使用所需分配器构造的结果字符串上使用成员函数,如 append 、 insert 和 operator+= 。

(C++11 起)

在重载版本 ( 4 ) 、 ( 7 ) 、 ( 12 ) 和 ( 16 ) 中使用 std:: type_identity_t 作为参数,确保 std:: basic_string < CharT, Traits, Allocator > 类型的对象始终可以与具有隐式转换到 std:: basic_string_view < CharT, Traits > 能力的 T 类型对象进行拼接,反之亦然,这符合 重载决议 规则。

功能测试 宏 值 标准 功能
__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 分配器传播存在随意性和不一致性 使其更加一致

另请参阅

向末尾追加字符
(公开成员函数)
向末尾追加字符
(公开成员函数)
插入字符
(公开成员函数)