Spec-Zone.ru › C++

std::operator+(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) (constexpr с C++20)
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) (constexpr с C++20)
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) (constexpr с C++20)
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) (constexpr с C++20)
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) (constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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)
(constexpr с C++20)
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()

Иными словами:

  • Если один из операндов является rvalue basic_string, используется его аллокатор.
  • В противном случае к аллокатору lvalue-операнда basic_string применяется select_on_container_copy_construction.

В каждом случае предпочтение отдаётся левому операнду, если оба операнда являются basic_string одного и того же значения категории.

Для (8-16) все rvalue-операнды basic_string остаются в допустимых, но неуточнённых состояниях.

(с C++11)

Параметры

lhs - строка, строковое представление(с C++26), символ или указатель на первый символ массива с завершающим нулём
rhs - строка, строковое представление(с C++26), символ или указатель на первый символ массива с завершающим нулём

Возвращаемое значение

Строка, содержащая символы из 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() + /* ... */; // 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+ аллокатор, используемый для конечного результата, можно задать, добавив в начало rvalue basic_string с нужным аллокатором:

// use my_favorite_allocator for the final result
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> всегда можно объединить с объектом типа 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 распространение аллокатора является непоследовательным и непредсказуемым поведение стало более последовательным

См. также

operator+=
добавляет символы в конец
(открытая функция-член)
append
добавляет символы в конец
(открытая функция-член)
insert
вставляет символы
(открытая функция-член)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/string/basic_string/operator%2B

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API