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
用于字符串连接,它是经典的 Schlemiel the Painter 算法,甚至比 C 中使用的通常示例更糟糕strcat
。如果没有 C++11 移动语义,它会为向量的每个元素产生两个不必要的累加器副本。即使使用移动语义,它仍然会为每个元素产生一个不必要的累加器副本。
上面的三个例子是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
必须是对非常量的引用,lambda 返回类型必须是引用(因此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{});