我最近一直在研究右值引用,并得出一个结论,即在要制作对象的完整拷贝的任何地方都使用按值传递是非常有利的(完整的理由参见例如 How to reduce redundant code when adding rvalue reference operator overloads? 和 Want speed? Pass by value! ),因为在 f(std::move(a));
等情况下编译器可以自动优化一个拷贝,其中 f
定义为 void f(A a);
.
pass-by-value-everywhere 的一个负面后果是所有代码都被 std::move
乱扔,即使在简单的情况下,例如:
void Object::value(A a)
{
value_ = std::move(a);
}
显然,如果我只写了以下内容:
void Object::value(A a)
{
value_ = a;
}
即使没有提示,编译器也应该不难识别 a
已接近其生命周期的尽头,并且不会用额外的拷贝来惩罚我。事实上,即使在复杂的函数中,编译器也应该能够识别这一点。
问题:
C++0x 标准是否允许这种优化?
编译器会使用它吗?即使在复杂的情况下,即函数由不止一行组成?
这种优化有多可靠,即我是否可以期望编译器像我期望编译器应用返回值优化一样多地利用它?
最佳答案
Is this optimization allowed by the C++0x Standard?
没有。
Do the compilers employ it? Even in complex cases, i.e. the function consists from more than one line?
没有。
How reliable is this optimization, i.e. can I expect the compiler to utilize it as much as I expect the compiler to apply Return Value Optimization?
你应该用 print 语句装饰 A(const A&)
和 A(A&&)
并运行你感兴趣的测试用例。如果这些用例是您设计的一部分,请不要忘记测试左值参数。
正确的答案取决于复制和 move A
的成本,Object::value
实际有多少参数,以及你重复多少代码'我愿意忍受。
最后,对任何包含“总是”或“无处不在”等字眼的指南非常怀疑。例如。我不时使用 goto
。但是其他程序员有像“从不”这样的词与 goto
相关联。但是每隔一段时间,您就无法在速度和清晰度方面击败 goto
。
有时你应该更喜欢一对 foo(const A&) foo(A&&)
而不是 foo(A)
。有时你不会。您对装饰拷贝和 move 成员的实验将为您提供指导。
关于c++ - 最后一次使用可 move 对象时,编译器会自动使用 move 语义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6089425/