C++03
std::string s;
for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i)
s += *i;
return s;
C++11 (MSVC 2010 サブセット)
std::string s;
std::for_each(v.begin(), v.end(), [&](const std::string &piece){ s += piece; });
return s;
C++11
std::string s;
for (const auto &piece : v) s += piece;
return s;
std::accumulate
文字列の連結には使用しないでください。これは古典的なシュレミエルのペインターのアルゴリズムであり、C で使用する通常の例よりもさらに悪いものですstrcat
。C++11 の移動セマンティクスがないと、ベクトルの各要素に対してアキュムレータの不要なコピーが 2 つ発生します。移動セマンティクスを使用しても、要素ごとにアキュムレータの不要なコピーが 1 つ発生します。
上記の 3 つの例はO(n)です。
std::accumulate
文字列の場合はO(n²)です。
std::accumulate
カスタム ファンクターを指定することで、文字列に対して O(n) を作成できます。
std::string s = std::accumulate(v.begin(), v.end(), std::string{},
[](std::string &s, const std::string &piece) -> decltype(auto) { return s += piece; });
s
は非 const への参照である必要があり、ラムダの戻り値の型は参照である必要があり (したがってdecltype(auto)
)、本体では
+=
notを使用する必要があることに注意してください+
。
C++20
C++20 になる予定の現在のドラフトでは、アキュムレータに追加するときに使用するように の定義std::accumulate
が変更されstd::move
ているため、C++20 以降でaccumulate
は、文字列に対して O(n)になり、使用できます。ワンライナーとして:
std::string s = std::accumulate(v.begin(), v.end(), std::string{});