如果我使用以下代码:
std::vector<std::string> foo{"foo","bar"};string res=""; res=std::accumulate(foo.begin(),foo.end(),res,[](string &rs,string &arg){ return rs+arg; });
我可以肯定会有临时对象构造.
在this回答他们说std :: accumulate的效果是这样指定的:
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.
所以我想知道这样做的正确方法是什么,以避免不必要的临时对象构造.
一个想法是以这种方式改变lambda:
[](string &rs,string &arg){ rs+=arg; return rs; }
在这种情况下,我认为我强制有效串联字符串并帮助编译器(我知道我shouldn’t)省略了不必要的副本,因为这应该等同于(伪代码):
accum = [](& accum,& arg){ ...; return accum; }
因此
accum = & accum;
另一个想法是使用
accum = [](& accum,& arg){ ...; return std::move(accum); }
但这可能会导致类似于:
accum = std::move(& accum);
这看起来很可疑.
写这个的正确方法是什么,以尽量减少不必要的临时对象创建的风险?我不只是对std :: string感兴趣,我很乐意有一个解决方案,这可能适用于任何具有复制和移动构造函数/赋值的对象.
解决方法 请尝试以下方法res=std::accumulate(foo.begin(),const string &arg) -> string & { return rs+=arg; });
在此通话之前可能会有一个电话
std::string::size_type n = std::accumulate( foo.begin(),std::string::size_type( 0 ),[] ( std::string_size_type n,const std::string &s ) { return ( n += s.size() ); } );res.reserve( n );总结
以上是内存溢出为你收集整理的c – 有效积累全部内容,希望文章能够帮你解决c – 有效积累所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)