假设我有字符串向量,我想通过 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; });
我可以很确定会有临时对象构造。
在这个答案中,他们说 std::accumulate 的效果是这样指定的:
通过使用初始值 init 初始化累加器 acc 来计算其结果,然后按顺序使用 acc = acc + *i 或 acc = binary_op(acc, *i) 为范围 [first,last) 中的每个迭代器 i 修改它。
所以我想知道这样做的正确方法是什么,以避免不必要的临时对象构造。
一个想法是以这种方式更改 lambda:
[](string &rs,string &arg){ rs+=arg; return rs; }
在这种情况下,我认为我强制字符串的有效连接并帮助编译器(我知道我不应该)省略不必要的副本,因为这应该等同于(伪代码):
accum = [](& accum,& arg){ ...; return accum; }
因此
accum = & accum;
另一个想法是使用
accum = [](& accum,& arg){ ...; return std::move(accum); }
但这可能会导致类似:
accum = std::move(& accum);
这在我看来非常可疑。
编写此代码以最大程度地减少不必要地创建临时对象的风险的正确方法是什么?我不仅对 std::string 感兴趣,我很高兴有一个解决方案,它可能适用于任何实现了复制和移动构造函数/分配的对象。