std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite
template< class Operation >
constexpr void resize_and_overwrite( size_type count, Operation op );
|
(seit C++23) | |
Ändert die Größe der Zeichenkette so, dass sie höchstens count Zeichen enthält, wobei die vom Benutzer bereitgestellte Operation op verwendet wird, um den möglicherweise unbestimmten Inhalt zu verändern und die Länge festzulegen. Dies vermeidet die Kosten für die Initialisierung einer passend großen std::string, wenn diese als Zeichen-Array verwendet werden soll, das z. B. durch einen C-API-Aufruf befüllt wird.
Diese Funktion führt die folgenden Schritte aus:
- Beschafft zusammenhängenden Speicher, der
count + 1Zeichen enthält, und macht seine erstenkZeichen gleich den erstenkZeichen von*this, wobeikdie kleinere voncountund dem Ergebnis vonsize()vor dem Aufruf vonresize_and_overwriteist. Seipder Zeiger auf das erste Zeichen im Speicher.- Die Gleichheit wird bestimmt, als ob
this->compare(0, k, p, k) == 0überprüft würde. - Die Zeichen in
[p + k,p + count]können unbestimmte Werte haben.
- Die Gleichheit wird bestimmt, als ob
- Wertet
std::move(op)(p, count)aus, seirder Rückgabewert. - Ersetzt den Inhalt von
*thisdurch[p,p + r)(wodurch die Länge von*thisaufrgesetzt wird). Macht alle Zeiger und Referenzen auf den Bereich[p,p + count]ungültig.
Wenn r nicht von einem ganzzahlartigen Typ ist, ist das Programm fehlerhaft (ill-formed).
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
std::move(op)(p, count)eine Ausnahme wirft.std::move(op)(p, count)podercountverändert.rnicht im Bereich[0,count]liegt.- Ein Zeichen im Bereich
[p,p + r)einen unbestimmten Wert hat.
Implementierungen wird empfohlen, unnötige Kopien und Allokationen zu vermeiden, z. B. indem p gleich dem Zeiger auf den Beginn des Speichers von Zeichen gemacht wird, die für *this nach dem Aufruf allokiert wurden, was identisch mit dem vorhandenen Speicher von *this sein kann, falls count kleiner oder gleich capacity() ist.
Parameter
| count | - | die maximal mögliche neue Größe der Zeichenkette |
| op | - | das Funktionsobjekt zum Festlegen der neuen Inhalte der Zeichenkette |
Exceptions
std::length_error
falls
count
>
max_size
(
)
.
Alle Ausnahmen, die vom entsprechenden
Allocator
geworfen werden.
Wenn eine Ausnahme aus std :: move ( op ) ( p, count ) geworfen wird, ist das Verhalten undefiniert. Andernfalls, wenn eine Ausnahme geworfen wird, hat diese Funktion keine Wirkung.
Hinweise
resize_and_overwrite
macht alle Iteratoren, Zeiger und Referenzen auf
*
this
ungültig, unabhängig davon, ob eine Reallokation stattfindet. Implementierungen können davon ausgehen, dass der Inhalt der Zeichenkette nach dem Aufruf von
resize_and_overwrite
nicht gealiast wird.
| Feature-Test Makro | Wert | Standard | Funktion |
|---|---|---|---|
__cpp_lib_string_resize_and_overwrite
|
202110L
|
(C++23) |
std::basic_string::resize_and_overwrite
|
Beispiel
Link zum Testen des Beispiels: compiler explorer .
#include <algorithm> #include <cassert> #include <cstddef> #include <cstring> #include <iomanip> #include <iostream> #include <string> #include <string_view> static_assert(__cpp_lib_string_resize_and_overwrite); constexpr std::string_view fruits[]{"Apfel", "Banane", "Kokosnuss", "Datum", "Elderberry"}; int main() { // Ein einfacher Fall, nur fruits[0] anhängen. Die String-Größe wird erhöht. std::string s{"Essen: "}; s.resize_and_overwrite(16, [sz = s.size()](char* buf, std::size_t buf_size) noexcept { const auto to_copy = std::min(buf_size - sz, fruits[0].size()); std::memcpy(buf + sz, fruits[0].data(), to_copy); return sz + to_copy; }); std::cout << "1. " << std::quoted(s) << '\n'; // Der Fall der Größenverringerung. Beachten Sie, dass die Lambda-Funktion des Benutzers immer aufgerufen wird. s.resize_and_overwrite(10, [](char* buf, int n) noexcept { return std::find(buf, buf + n, ':') - buf; }); std::cout << "2. " << std::quoted(s) << '\n'; std::cout << "3. Kopiere Daten, bis der Puffer voll ist. Drucke Daten und Größen.\n"; std::string food{"Essen:"}; const auto resize_to{27}; std::cout << "Anfänglich, food.size: " << food.size() << ", food.capacity: " << food.capacity() << ", resize_to: " << resize_to << ", food: " << std::quoted(food) << '\n'; food.resize_and_overwrite ( resize_to, [food_size = food.size()](char* p, std::size_t n) noexcept -> std::size_t { // p[0]..p[n] ist der zuweisbare Bereich // p[0]..p[min(n, food_size) - 1] ist der lesbare Bereich // (Inhalt anfangs gleich dem ursprünglichen String) // Debug-Ausgabe: std::cout << "In Operation(); n: " << n << '\n'; // Kopiere Früchte in den Puffer p, solange genügend Platz vorhanden ist. char* first = p + food_size; for (char* const end = p + n; const std::string_view fruit : fruits) { char* last = first + fruit.size() + 1; if (last > end) break; *first++ = ' '; std::ranges::copy(fruit, first); first = last; } const auto final_size{static_cast<std::size_t>(first - p)}; // Debug-Ausgabe: std::cout << "In Operation(); final_size: " << final_size << '\n'; assert(final_size <= n); return final_size; // Rückgabewert ist die tatsächliche neue Länge // des Strings, muss im Bereich 0..n liegen } ); std::cout << "Finally, food.size: " << food.size() << ", food.capacity: " << food.capacity() << ", food: " << std::quoted(food) << '\n'; }
Mögliche Ausgabe:
1. "Food: apple" 2. "Food" 3. Kopiere Daten, bis der Puffer voll ist. Drucke Daten und Größen. Anfangs, food.size: 5, food.capacity: 15, resize_to: 27, food: "Food:" In Operation(); n: 27 In Operation(); final_size: 26 Schließlich, food.size: 26, food.capacity: 30, food: "Food: apple banana coconut"
Siehe auch
|
ändert die Anzahl der gespeicherten Zeichen
(öffentliche Elementfunktion) |