std::basic_string<CharT,Traits,Allocator>:: resize_and_overwrite
|
template
<
class
Operation
>
constexpr void resize_and_overwrite ( size_type count, Operation op ) ; |
(depuis C++23) | |
Redimensionne la chaîne pour contenir au plus count caractères, en utilisant l'opération fournie par l'utilisateur op pour modifier les contenus potentiellement indéterminés et définir la longueur. Cela évite le coût d'initialisation d'une std::string de taille appropriée lorsqu'elle est destinée à être utilisée comme un tableau de caractères à remplir par, par exemple, un appel d'API C.
Cette fonction effectue les étapes suivantes :
-
Obtient un stockage contigu qui contient
count
+
1
caractères, et rend ses premiers
k
caractères égaux aux premiers
k
caractères de
*
this
, où
k
est le plus petit entre
count
et le résultat de
size
(
)
avant l'appel à
resize_and_overwrite. Soit p le pointeur vers le premier caractère du stockage.- L'égalité est déterminée comme si on vérifiait this - > compare ( 0 , k, p, k ) == 0 .
-
Les caractères dans
[p + k,p + count]peuvent avoir des valeurs indéterminées.
- Évalue std :: move ( op ) ( p, count ) , soit r la valeur de retour.
-
Remplace le contenu de
*
this
par
[p,p + r)(ce qui définit la longueur de * this à r ). Invalide tous les pointeurs et références vers la plage[p,p + count].
Si r n'est pas d'un type similaire à un entier , le programme est mal formé.
Si l'une des conditions suivantes est satisfaite, le comportement est indéfini :
- std :: move ( op ) ( p, count ) lève une exception.
- std :: move ( op ) ( p, count ) modifie p ou count .
-
r
n'est pas dans l'intervalle
[ 0 ,count]. -
Tout caractère dans l'intervalle
[p,p + r)a une valeur indéterminée.
Il est recommandé que les implémentations évitent les copies et allocations inutiles en, par exemple, rendant p égal au pointeur vers le début du stockage des caractères alloués pour * this après l'appel, qui peut être identique au stockage existant de * this si count est inférieur ou égal à capacity ( ) .
Table des matières |
Paramètres
| count | - | la taille maximale possible de la nouvelle chaîne |
| op | - | l'objet fonction utilisé pour définir le nouveau contenu de la chaîne |
Exceptions
std::length_error
si
count
>
max_size
(
)
.
Toute exception levée par l'allocateur correspondant
Allocator
.
Si une exception est levée depuis std :: move ( op ) ( p, count ) , le comportement est indéfini. Sinon, si une exception est levée, cette fonction n'a aucun effet.
Notes
resize_and_overwrite
invalide tous les itérateurs, pointeurs et références vers
*
this
, indépendamment du fait qu'une réallocation se produise ou non. Les implémentations peuvent supposer que le contenu de la chaîne n'est pas aliasé après l'appel à
resize_and_overwrite
.
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_string_resize_and_overwrite
|
202110L
|
(C++23) |
std::basic_string::resize_and_overwrite
|
Exemple
Lien pour tester l'exemple : 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[]{"pomme", "banane", "noix de coco", "date", "baie de sureau"}; int main() { // Un cas simple, ajouter uniquement fruits[0]. La taille de la chaîne sera augmentée. std::string s{"Nourriture : "}; s.redimensionner_et_écraser(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'; // Le cas de réduction de taille. Notez que la lambda de l'utilisateur est toujours invoquée. s.redimensionner_et_écraser(10, [](char* buf, int n) noexcept { return std::find(buf, buf + n, ':') - buf; }); std::cout << "2. " << std::quoted(s) << '\n'; std::cout << "3. Copier les données jusqu'à ce que le tampon soit plein. Afficher les données et les tailles.\n"; std::string food{"Nourriture :"}; const auto resize_to{27}; std::cout << "Initialement, food.size: " << food.size() << ", food.capacity: " << food.capacity() << ", redimensionner_à: " << resize_to << ", nourriture: " << std::quoted(food) << '\n'; food.redimensionner_et_écraser ( resize_to, [food_size = food.size()](char* p, std::size_t n) noexcept -> std::size_t { // p[0]..p[n] est la plage assignable // p[0]..p[min(n, food_size) - 1] est la plage lisible // (contenu initialement égal à la chaîne originale) // Impression de débogage : std::cout << "Dans Operation(); n: " << n << '\n'; // Copier les fruits dans le tampon p tant qu'il y a suffisamment d'espace. 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)}; // Impression de débogage : std::cout << "In Operation(); taille_finale: " << final_size << '\n'; assert(final_size <= n); return final_size; // La valeur de retour est la nouvelle longueur réelle // de la chaîne, doit être dans l'intervalle 0..n } ); std::cout << "Enfin, food.size: " << food.size() << ", food.capacity: " << food.capacity() << ", nourriture: " << std::quoted(food) << '\n'; }
Sortie possible :
1. "Nourriture : pomme" 2. "Nourriture" 3. Copier les données jusqu'à ce que le tampon soit plein. Afficher les données et les tailles. Initialement, food.size : 5, food.capacity : 15, resize_to : 27, food : "Nourriture :" Dans Operation() ; n : 27 Dans Operation() ; final_size : 26 Finalement, food.size : 26, food.capacity : 30, food : "Nourriture : pomme banane noix de coco"
Voir aussi
|
modifie le nombre de caractères stockés
(fonction membre publique) |