2016-11-23 1 views
2

J'ai du code qui combine divers éléments dans un tampon. Mon code ressemble à ceci:Existe-t-il une façon plus simple de combiner std :: string dans std :: vector <char>?

static void CreatePacket(const std::string& source, const std::string id, const std::string payload, std::vector<char>& buffer) 
{ 
    buffer.resize(source.size() + id.size() + payload.size()); 
    std::vector<char>::iterator bufferDest = buffer.begin(); 

    // Start the message 
    char MessageStart = '$'; 
    *bufferDest = MessageStart; 
    ++bufferDest; 

    // Copy the message source 
    std::copy(source.begin(), source.end(), bufferDest); 
    bufferDest += source.size(); 

    // Copy the message id 
    std::copy(id.begin(), id.end(), bufferDest); 
    bufferDest += id.size(); 
} 

Cette méthode est appelée comme suit:

std::vector<char> buffer; 

std::string source = "AB"; 
std::string id = "CDE"; 
std::string payload = "payload"; 

CreatePacket(source, id, payload, buffer); 

Je suis encore un peu vert sur le chemin std de faire les choses, mais ma mise en œuvre se sent un peu maladroit (spécifiquement, avoir à incrémenter explicitement le bufferDest après chaque copie). Y a-t-il une façon plus propre de faire cela?

Mon compilateur ne prend pas en charge C++ 11 si cela fait une différence.

+0

vous n'avez pas besoin d'incrémenter explicitement la 'bufferDest',' std :: copy' retour qui vous –

Répondre

3

Vous pouvez simplement utiliser un vector::insert() overload approprié pour ajouter le contenu d'un string à la fin de la vector (pas besoin de compliquer le code à l'aide std::copy ou std::back_inserter comme montré dans d'autres réponses), par exemple:

buffer.insert(buffer.end(), source.begin(), source.end()); 

Ainsi, votre fonction ressemblerait à ceci:

void CreatePacket(const std::string& source, 
        const std::string& id, 
        const std::string& payload, 
        std::vector<char>& buffer) 
{ 
    buffer.clear(); 
    buffer.reserve(source.size() + id.size() + payload.size() + 1); 

    buffer.push_back('$'); 

    buffer.insert(buffer.end(), source.begin(), source.end()); 
    buffer.insert(buffer.end(), id.begin(),  id.end() ); 
    buffer.insert(buffer.end(), payload.begin(), payload.end()); 
} 
+0

Pour le profane, cela ne semble pas très différent de la réponse de Danh. Y a-t-il un avantage à le faire de cette façon? –

+0

@JonCage: Ceci est différent de cette réponse, car Danh utilise 'std :: copy' et' std :: back_inserter', à la place je viens d'utiliser 'std :: vector :: insert', donc ce code est plus simple. –

+0

@ MrC64 - Je n'avais pas l'intention de suggérer qu'ils étaient les mêmes, juste pour un débutant de la STL, ils ont l'air aussi complexes les uns que les autres. J'étais juste intéressé à savoir pourquoi on pourrait choisir l'un contre l'autre. Après avoir regardé les deux pendant un moment, je peux voir que le tien a l'air un peu plus facile de voir quelle est l'intention. –

8

Je pense que c'est beaucoup plus clair.

void CreatePacket(const std::string& source, const std::string& id, const std::string& payload, std::vector<char>& buffer) 
{ 
    buffer.clear(); 
    buffer.reserve(source.size() + id.size() + payload.size() + 1); 

    buffer.push_back('$'); 

    std::copy(source.begin(), source.end(), std::back_inserter(buffer)); 
    std::copy(id.begin(), id.end(), std::back_inserter(buffer)); 
    std::copy(payload.begin(), payload.end(), std::back_inserter(buffer)); 
} 
+0

Oui! C'est exactement le genre de chose que j'avais à l'esprit :-) –

+0

@JonCage: Vous pouvez réellement simplifier votre code: le 'std :: copy' et le' std :: back_inserter' ne sont pas nécessaires, sauf si quelque chose me manque. Vous pouvez juste utiliser 'std :: vector :: insert', comme montré dans mon autre réponse. –

+0

@ Mr.C64 - Quels sont les avantages de faire votre suggestion par rapport à cela? Ils ont tous deux l'air des solutions assez viables pour moi. ;) –

2

Il est presque propre, sauf que vous pouvez utiliser la valeur de retour de std::copy et donc se débarrasser de l'augmentation explicite de bufferDest:

static void CreatePacket(const std::string& source, const std::string id, const std::string payload, std::vector<char>& buffer) 
{ 
    buffer.resize(source.size() + id.size() + payload.size()); 
    std::vector<char>::iterator bufferDest = buffer.begin(); 

    // Start the message 
    char MessageStart = '$'; 
    *bufferDest = MessageStart; 
    ++bufferDest; 

    // Copy the message source 
    bufferDest = std::copy(source.begin(), source.end(), bufferDest); 

    // Copy the message id 
    bufferDest= std::copy(id.begin(), id.end(), bufferDest); 
}