Namespaces
Variants

std::basic_string<CharT,Traits,Allocator>:: resize_and_overwrite

From cppreference.net
std::basic_string
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 :

  1. 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.
  2. Évalue std :: move ( op ) ( p, count ) , soit r la valeur de retour.
  3. 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)