高效积累 [英] Efficient accumulate
问题描述
假设我有字符串向量,我想通过std :: accumulate将它们连接起来.
Assume I have vector of strings and I want concatenate them via std::accumulate.
如果我使用以下代码:
std::vector<std::string> foo{"foo","bar"};
string res="";
res=std::accumulate(foo.begin(),foo.end(),res,
[](string &rs,string &arg){ return rs+arg; });
我可以肯定会有临时的对象构造.
I can be pretty sure there will be temporary object construction.
在此答案中,他们说std :: accumulate的效果是这样指定的:
In this answer they say that the effect of std::accumulate is specified this way:
通过使用以下参数初始化累加器acc来计算其结果初始值init,然后使用acc = acc + * i或acc =对其进行修改对于范围为[first,last)的每个迭代器i,binary_op(acc,* i)订单.
Computes its result by initializing the accumulator acc with the initial value init and then modifies it with acc = acc + *i or acc = binary_op(acc, *i) for every iterator i in the range [first,last) in order.
所以我想知道这样做的正确方法是什么,以避免不必要的临时对象构造.
So I'm wondering what is the correct way to do this to avoid the unnecessary temporary object construction.
一个想法是通过这种方式更改lambda:
One idea was to change the lambda this way:
[](string &rs,string &arg){ rs+=arg; return rs; }
在这种情况下,我以为我强制了字符串的有效连接并帮助了编译器(我知道我
In this case, I thought I force efficient concatenation of the strings and help the compiler (I know I shouldn't) omit the unnecessary copy, since this should be equivalent to (pseudocode):
accum = [](& accum,& arg){ ...; return accum; }
因此
accum = & accum;
另一个想法是使用
accum = [](& accum,& arg){ ...; return std::move(accum); }
但这可能会导致类似以下情况:
But this would probably lead to something like:
accum = std::move(& accum);
对我来说,哪个看起来非常可疑.
Which looks very suspicious to me.
编写此代码以最大程度地减少不必要地创建临时对象的风险的正确方法是什么?我不仅对std :: string感兴趣,我很高兴有一个解决方案,该解决方案可能对已实现复制和移动构造函数/赋值的任何对象都有效.
What is the correct way to write this to minimize the risk of the unnecessary creation of temporary objects? I'm not just interested in std::string, I'd be happy to have a solution, that would probably work for any object that has copy and move constructors/assignments implemented.
推荐答案
尝试以下操作
res=std::accumulate(foo.begin(),foo.end(),res,
[](string &rs, const string &arg) -> string & { return rs+=arg; });
在此通话之前,可能会有通话的感觉
Before this call maybe there is a sence to call
std::string::size_type n = std::accumulate( foo.begin(), foo.end(),
std::string::size_type( 0 ),
[] ( std::string_size_type n, const std::string &s ) { return ( n += s.size() ); } );
res.reserve( n );
这篇关于高效积累的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!