我的问题很简单:我有一个动态的对象数组 返回字符串的方法。我想将所有这些字符串连接在一起。
如果我有一个字符串数组而不是一个返回a的方法的对象 字符串,这将是一项微不足道的任务:
std::vector<std::string> v{ "f", "o", "o" };
std::string const x = std::accumulate(v.begin(), v.end(), std::string());
但在我的情况下,它看起来像这样:
struct foo
{
foo(std::string const & name) : name_(name) {}
std::string const & name() const { return name_; }
private:
std::string const name_;
};
std::vector<foo> v{ foo("f"), foo("o"), foo("o") };
我想使用标准库算法,因为我确信它们是 高效和我无需调试的东西,但这太难阅读了 并理解:
std::vector<std::string> transformed(v.size());
std::transform(v.begin(), v.end(), transformed.begin(),
[](foo const & f) { return f.name(); });
std::string const x = std::accumulate(transformed.begin(), transformed.end(),
std::string());
未来的维护者可能(并且理所当然地)追捕我 面对不必要地使一项简单的任务复杂化,我本来可以 完成:
std::string x;
for(auto const & f : v)
x += f.name();
这里有什么比我更容易看到的东西,或者确实如此 应该让标准库休息,并使用for循环(即 什么积累归结为无论如何)?
答案 0 :(得分:6)
如果您坚持使用STL,则还有std::accumulate
的另一个版本:
template< class InputIt, class T, class BinaryOperation >
T accumulate( InputIt first, InputIt last, T init, BinaryOperation op );
然后您的代码可以成为
std::string const x = std::accumulate(v.begin(), v.end(), std::string(),
[](std::string a, foo const& b){return a += b.name();});
编辑:也许更多的版权省略宣言
答案 1 :(得分:2)
我只想使用for循环方法。它更容易阅读,而不是你需要调试或测试的东西(至少不是你编写自己的某种算法的同一级别)。仅仅因为它不是一个利用std库的解决方案并不意味着它是一个易于维护的合理解决方案。
答案 2 :(得分:0)
您可以编写operator + =。
的东西std::string & operator +=( std::string &s, const Foo &f )
{
return ( s += f.name() );
}
答案 3 :(得分:0)
我没有看到std :: for_each,std :: accumulate将如何为你带来性能上的胜利(你的向量是否足够重要?)。如果对您很重要,您可能需要进行时序分析。
当它不是性能关键时,我会考虑使用复杂性的可读性和可维护性。