2016-11-23 5 views
2

私はバッファにさまざまな要素を組み合わせたコードをいくつか持っています。次のようにメソッドが呼び出されていることstd :: stringを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(); 
} 

::私のコードは次のようになります

std::vector<char> buffer; 

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

CreatePacket(source, id, payload, buffer); 

私はまだ物事のstd途中で少し緑んだけど、私の実装は少し不格好な感じ(具体的には、各コピーの後にbufferDestを明示的にインクリメントする必要があります)。これを行うためのよりクリーンな方法がありますか?

違いがある場合、マイコンパイラはC++ 11をサポートしていません。

+0

あなたが明示的に 'bufferDest'、'のstd ::あなたにそれを返すcopy' –

答えて

3

あなただけのコンテンツを追加するために、適切なvector::insert() overloadを使用することができますvector(他の回答で示したようにstd::copy又はstd::back_inserterを使用してコードを複雑にする必要はありません)の終わりにstring、例えば:

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

は、だからあなたの関数は次のようになります。

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

素人には、これはダンの答えと大きく違って見えません。このようにすることに利点はありますか? –

+0

@JonCage:これはDanhが 'std :: copy'と' std :: back_inserter'を使う代わりに、私は単に 'std :: vector :: insert'を使っているので、このコードは簡単です。 –

+0

@ MrC64 - 私は彼らが同じであることを示唆するつもりはなかった、ちょうどSTL初心者に、彼らはお互いに複雑に見える。私はちょうど1つが他と対を選ぶ理由についてちょうど興味があった。私はあなたのものが意図が何であるかを少し見やすく見ていることがわかります。 –

8

これははるかに明確だと思います。

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

はいを​​インクリメントする必要はありません! –

+0

@JonCage:実際にコードをさらに単純化することができます。何かが見つからない限り、 'std :: copy'と' std :: back_inserter'は必要ありません。私の他の答えに示されているように 'std :: vector :: insert'を使うことができます。 –

+0

@ Mr.C64 - これに対してあなたの提案をする利点は何ですか?彼らはどちらも私にとってかなり実行可能なソリューションのように見えます。どちらも私のコードより良く見える;-) –

2

それはあなたがstd::copyからの戻り値を使用することができますので、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); 
} 
関連する問題