[英]Vector building optimization using std::move
我正在构建一些std::vector<Obj>
,其中Obj
是可以移动构造和分配的大对象(想想Obj
是大向量)。 代码通常是一个循环,例如
std::vector<Obj> v;
while (...) {
Obj foo = some client code(...);
// ... some complicated stuff modifying foo
v.push_back(foo);
}
如您所见,将foo
推入向量后就不再需要了。
我的问题是
写有意义吗
v.push_back(std::move(foo));
向编译器表明它可以获取 foo 的内容。
如果需要,是否真的需要? 实际上,编译器可能会注意到foo
在被推送后立即被破坏,以便可以移动它......实际的编译器是否使用这些类型的优化?
除非在非常特殊的情况下,否则不允许编译器在您未明确移动(即转换为右值引用;可能通过标准移动)的情况下调用移动构造函数或省略对象。
A) object 是临时未命名的 object。
B) object 从 function 返回。
还有一些其他要求,但以上两个都不适用于此处。 所以不允许转换为移动/省略。
编译器有时可以使用 as-if 规则将副本转为移动,然后销毁,但这非常困难且通常很脆弱,因此您永远不要依赖它。
编译器是否可以优化它取决于Obj
到底是什么样子,在做“复杂的东西修改foo
”时调用什么函数, Obj
是否有移动构造函数,等等。 您应该尝试对代码进行编译和基准测试并亲自查看,或者使用像https://godbolt.org/这样的在线服务来查看生成的汇编代码。
但是,最好的方法是完全避免复制或移动。 您可以通过调用emplace_back()
直接在向量中构造一个Obj
来完成此操作,然后就地修改它,如下所示:
while (...) {
v.emplace_back();
Obj &foo = v.back();
// ... some complicated stuff modifying foo
}
你可以用 C++17 写得稍微短一些:
while (...) {
Obj &foo = v.emplace_back();
// ... some complicated stuff modifying foo
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.