7
votes

Comment puis-je lancer `std :: string` to` std :: vecteur `Sans faire une copie?

Il existe une fonction de bibliothèque que je souhaite appeler la signature dont la signature est la suivante: xxx pré>

J'ai un std :: string code> variable, je veux l'envoyer cette fonction En tant qu'argument. P>

void WriteString(const std::string & TextData)
{
    // ...
    WriteBinary(TextData);  // <-- How to make this line work?
    // ...
}


6 commentaires

J'ai trouvé beaucoup de questions sur la conversion inverse, mais je n'ai rien trouvé exactement sur la coulée de la chaîne au vecteur. Si cela est arrivé à être un duplicata, je m'excuse à l'avance.


C'est pourquoi la bibliothèque standard utilise toujours une paire d'itérateurs pour spécifier une séquence, de sorte que vous ne rencontrez pas ce problème.


Si cela existait, il faudrait presque certainement être std :: échange (textdata, myvector) , mais comme les réponses disent, cela n'existe pas.


Si tous les types de données séquentiels dans STL seraient implémentées, disent, une séquence abstraite séquence <> , vous auriez pu l'avoir fait en enveloppant vos chaînes dans un string_based_essence <> classe . Cependant, ce n'est pas le cas. Et STL est censé être orienté objet ...


Euh, c ++ est un peu cassé à cet égard :) me rappelle mon cas avec deux cordes mais un autre allocateur . J'ai fait ce que je voulais, mais il n'y a pas de moyen sûr, surtout dans votre cas. Vous devrez prendre des risques :)


@ ESeraygün: Non, la STL n'était pas censée être orientée objet. . BTW, la surcharge d'accès virtuel aurait tué std :: vecteur , et nous utiliserions toujours t [] .


4 Réponses :


5
votes

J'ai peur que ce n'était pas possible. Ni chaîne ni vecteur a un constructeur qui lui permettrait de "adopter" un tampon préexistant. Et il est très probable que la disposition de la mémoire d'une chaîne et un vecteur diffère, il n'y a donc pas de coulée possible.


0 commentaires

11
votes

Il n'y a aucun moyen de le faire, car les dispositions des deux types ne sont pas garanties d'une manièreone similaire.

La meilleure approche consiste à corriger writebinary pour utiliser "itérateurs". : xxx

ou modèle IT: xxx

et ensuite vous pouvez l'utiliser pour les chaînes, les vecteurs ou tout autre conteneur Vous aimez!

Sinon, vous pouvez utiliser le constructeur d'itérateur pour effectuer la copie aussi efficacement que possible: xxx


0 commentaires

2
votes

Y a-t-il une façon de pouvoir envoyer directement la variable STD :: String sans en faire une copie? P>

Non, certainement pas en toute sécurité. P>

Si vous avez le contrôle de la bibliothèque, je suggérerais un léger refacteur. P>

Ajouter: P>

void WriteBinary(std::vector<uint8_t> const& vec)
{ WriteBinary(vec.begin(), vec.end()); }

void WriteString(std::string const& s)
{ WriteBinary(s.begin(), s.end()); }

0 commentaires

1
votes

Vous êtes bien sûr libre de vous piéger pour obtenir le résultat souhaité. Mais vous devez vous préparer à une exécution sommaire des collègues ou des personnes qui souhaitent utiliser / gérer / modifier ou portez votre code ...

... ne le faites pas! ... H1>
template <typename T>
class vector
{
  T* _first, _last, _end;
  std::allocator<T> _alloc;
};


2 commentaires

C'est la vraie réponse à ma question. Merci. Cependant, je serai conforme à votre recommandation et je ne vais pas l'utiliser. Je vais transmettre des itérateurs à cette fin de la manière dont les autres réponses ont suggérées.


Vous devriez au moins mentionner que cette réponse est extrêmement dépendante de la mise en œuvre interne de std :: vecteur et std :: string dans la norme particulière bibliothèque utilisée.