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 le contenu éventuellement indéterminé et définir la longueur. Cela évite le coût d'initialisation d'un std::string de taille appropriée lorsqu'il est destiné à être utilisé 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 contenant
count + 1caractères, et rend ses premierskcaractères égaux aux premierskcaractères de*this, oùkest le plus petit decountet du résultat desize()avant l'appel àresize_and_overwrite. Soitple pointeur vers le premier caractère dans le 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.
- L'égalité est déterminée comme si on vérifiait
- Évalue
std::move(op)(p, count), soitrla valeur de retour. - Remplace le contenu de
*thispar[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 de type 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)modifiepoucount.rn'est pas dans la plage[0,count].- Tout caractère dans la plage
[p,p + r)a une valeur indéterminée.
Il est recommandé aux implémentations d'éviter les copies et allocations inutiles en, par exemple, faisant en sorte que p soit égal au pointeur du 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().
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) |