什么样的参数可以在返回语句中自动移动
What kind of parameters can be automatically moved in return statements?
Andrew Koenig写了一篇题为"某些优化比其他优化更重要"的文章,其中包含以下两个函数定义:
string rev(string s) {
reverse(s.begin(), s.end());
return s; // GCC-4.8 uses move constructor
}
string rev(string&& s) {
reverse(s.begin(), s.end());
return s; // GCC-4.8 uses copy constructor
}
文章暗示第二个函数(与const string&
过载相结合)比第一个函数更有效。然而,当我用GCC-4.8测试它时,我并没有看到这一点。第一个函数在return
语句中移动对象s
,而第二个函数复制对象。如果我将第二个函数中的return语句更改为return move(s);
,那么在这两种情况下,对象都将被移动。
问题:什么样的参数可以在return
语句中自动移动?更具体地说,声明为非常量右值引用的参数是否可以自动移动?
唯一可以通过return语句自动移动的变量是:
- 是自动变量
- 在函数的作用域中声明,从而保证它们在函数退出时被销毁
- 是值类型的变量
#3消除了任何类型的引用。如果你想从引用中移动,你必须明确地说要从它中移动
然而,如果你想知道为什么后者会更有效,这与移动次数有关。
在第一种情况下,您可以将复制/移动到函数参数s
中。用户必须将一些字符串复制或移动到参数中。然后参数的数据被移回。
在第二种情况下,您既没有复制也没有移动到函数参数中;它只是引用一个现有的对象。如果用户调用右值引用版本,则会有一个参数的输出的副本。
因此,第一种情况有一个拷贝/移动和一个移动,而不是一个拷贝。因此,如果用户正在复制参数,由于额外的移动,您的第一种情况会更慢。
行动不是自由的。它可能便宜(相对于复制),但它不是免费的2步比1步贵。如果用户调用const&
版本,则意味着他们要求复制字符串。因此,他们得到了一份副本,然后采取了几乎肯定会被取消的行动。
就我个人而言,我会权衡两次实现相同功能带来的微小效率提升和令人头疼的问题。在某些情况下,这可能是值得的。但我不会理所当然地这么做。
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 我的简单if-else语句是如何无法访问的代码
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么是0;C++中的有效语句
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- Insert函数不适用于2 if语句C++
- C++:我应该在 return 语句中显式使用 std::move() 来强制移动吗?
- 为什么结构化绑定禁用RVO和移动返回语句
- 如何在COUT语句中使用移动运算符
- C++11 是否保证 return 语句中的局部变量将被移动而不是复制?
- If/Else 语句在 2D 数组中移动时出现问题
- 复制 ELISION:在 return 语句中使用三元表达式时未调用移动构造函数
- 为什么我的 switch 语句不能移动到下一个案例?
- 什么样的参数可以在返回语句中自动移动
- return语句何时需要显式移动
- 如果函数调用是返回语句,编译器可以自动移动函数参数吗?