Namensräume
Varianten
Aktionen

std::operator+(std::basic_string)

Von cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
 
Definiert in Header <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 seit 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 seit 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 seit 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) (seit 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 seit 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 seit 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) (seit 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) (seit C++11)
(constexpr seit 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) (seit C++11)
(constexpr seit 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) (seit C++11)
(constexpr seit 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) (seit C++11)
(constexpr seit 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) (seit 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) (seit C++11)
(constexpr seit 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) (seit C++11)
(constexpr seit 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) (seit C++11)
(constexpr seit 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) (seit C++26)

Gibt einen String zurück, der die Zeichen von lhs gefolgt von den Zeichen von rhs enthält. Äquivalent zu

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); abgesehen davon, dass sowohl lhs als auch rhs in einem gültigen, aber undefinierten Zustand verbleiben. Wenn lhs und rhs gleiche Allokatoren haben, kann die Implementierung von einem davon verschieben.
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);

Der für das Ergebnis verwendete Allokator ist

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()

Mit anderen Worten

  • Wenn ein Operand ein basic_string rvalue ist, wird dessen Allokator verwendet.
  • Andernfalls wird select_on_container_copy_construction auf dem Allokator des lvalue basic_string-Operanden verwendet.

In jedem Fall wird der linke Operand bevorzugt, wenn beide basic_strings mit der gleichen Wertkategorie sind.

Für (8-16) bleiben alle rvalue basic_string Operanden in einem gültigen, aber undefinierten Zustand.

(seit C++11)

Inhalt

[bearbeiten] Parameter

lhs - String, String-Ansicht(seit C++26), Zeichen oder Zeiger auf das erste Zeichen eines null-terminierten Arrays
rhs - String, String-Ansicht(seit C++26), Zeichen oder Zeiger auf das erste Zeichen eines null-terminierten Arrays

[bearbeiten] Rückgabewert

Ein String, der die Zeichen von lhs gefolgt von den Zeichen von rhs enthält, unter Verwendung des wie oben ermittelten Allokators(seit C++11).

Anmerkungen

operator+ sollte mit großer Vorsicht bei zustandsbehafteten Allokatoren verwendet werden (z. B. wenn std::pmr::string verwendet wird)(seit C++17). Vor P1165R1 wurde der für das Ergebnis verwendete Allokator durch einen zufälligen Zufall bestimmt und konnte von Überladung zu Überladung aus keinem ersichtlichen Grund variieren. Darüber hinaus variiert für (1-5) das Allokator-Propagationsverhalten zwischen größeren Standardbibliotheksimplementierungen und weicht vom im Standard dargestellten Verhalten ab.

Da der von den Ergebnissen von operator+ verwendete Allokator von der Wertkategorie abhängt, ist operator+ hinsichtlich der Allokator-Propagierung nicht assoziativ.

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

Für eine Kette von operator+-Aufrufen kann der für das Endergebnis verwendete Allokator gesteuert werden, indem ein rvalue basic_string mit dem gewünschten Allokator vorangestellt wird.

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

Für eine bessere und portable Kontrolle über Allokatoren sollten Memberfunktionen wie append, insert und operator+= auf einem Ergebnisstring verwendet werden, der mit dem gewünschten Allokator konstruiert wurde.

(seit C++11)

Die Verwendung von std::type_identity_t als Parameter in den Überladungen (4), (7), (12) und (16) stellt sicher, dass ein Objekt vom Typ std::basic_string<CharT, Traits, Allocator> gemäß den Regeln der Überladungsauflösung immer an ein Objekt eines Typs T mit impliziter Konvertierung in std::basic_string_view<CharT, Traits> und umgekehrt angehängt werden kann.

Feature-Test-Makro Wert Std Feature
__cpp_lib_string_view 202403 (C++26) Verkettung von Strings und String-Ansichten, Überladungen (4), (7), (12), (16)
(seit C++26)

[bearbeiten] Beispiel

#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
}

Ausgabe

Hello world!
Hello Waterworld!

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
P1165R1 C++11 Allokator-Propagierung ist laienhaft und inkonsistent konsistenter gemacht

[bearbeiten] Siehe auch

hängt Zeichen am Ende an
(public member function) [edit]
hängt Zeichen am Ende an
(public member function) [edit]
fügt Zeichen ein
(public member function) [edit]