Namespaces
Variants

std::operator+(std::basic_string)

ja.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 の右辺値である場合、そのアロケータが使用されます。
  • そうでない場合、左辺値の select_on_container_copy_construction オペランドのアロケータに basic_string が使用されます。

いずれの場合も、両方が同じ値カテゴリの 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 > 型のオブジェクトと、 T 型のオブジェクト( std:: basic_string_view < CharT, Traits > への暗黙変換を持つ)との間で、常に連結が可能であることが保証されます。これは オーバーロード解決 の規則に従います。

機能テスト マクロ 値 標準 機能
__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 allocator propagation is haphazard and inconsistent made more consistent

関連項目

末尾に文字を追加する
(public member function)
末尾に文字を追加する
(public member function)
文字を挿入する
(public member function)