返回值优化:显式移动还是隐式
Return Value Optimization: Explicit move or implicit?
我有一个这样的函数,我必须在这里显式使用move还是它是隐式的?
std::vector<int> makeVector();
std::vector<int> makeVector2();
std::optional<std::vector<int>> getVectOr(int i) {
if(i==1) {
std::vector<int> v = makeVector();
return std::move(v);
}
else if(i==2) {
std::vector<int> v2 = makeVector2();
return std::move(v2);
}
return std::nullopt;
}
是否使用std::move
并不重要。此处不会进行返回值优化。RVO有几个要求。
返回值优化的要求之一是,返回的值必须是与函数返回的类型相同的。
std::optional<std::vector<int>> getVectOr(int i)
您的函数返回std::optional<std::vector<int>>
,因此只有相同类型的临时副本才会被消除。在这里讨论的两个return
语句中,两个临时语句都是std::vector<int>
,它们当然不是同一类型,所以不会发生RVO。
无论发生什么,您都会返回std::optional<std::vector<int>>
。这是绝对的要求。没有例外。但是,从这个函数返回一些东西的冒险总是从std::vector<int>
开始的。无论你尝试什么,你都不能把它变成一个完全不同的类型。在这一过程中,必须在某个地方建造一些东西。无返回值优化。
但话虽如此:这里也有移动语义的作用。如果幸运的是,星星对你来说是对齐的(这很可能(,那么移动语义将允许一切都发生,而无需复制大向量的内容。因此,尽管没有进行回报值优化,但您可能会赢得彩票,并在不打乱所有RAM中向量的实际内容的情况下实现一切。您可以自己使用调试器来确认或否认您是否中了该帐户的彩票。
您也可能有其他类型的RVO,即return
从函数中获取非易失性自动作用域对象:
std::optional<std::vector<int>> getVectOr(int i) {
std::optional<std::vector<int>> ret;
// Some code
return ret;
}
这里也可以进行返回值优化,这是可选的,但不是强制性的。
除了已经说过的:
在返回语句中使用std::move
禁止返回值优化。只有当返回语句的操作数是函数体中声明的自动非易失性存储变量的名称,并且其类型等于(直到cv限定(返回类型时,才允许命名返回值优化。
std::move(v2)
不符合此条件。它并不是简单地命名一个变量。
命名返回值优化也从来不是强制性的。它是可选的,取决于编译器是否执行它(即使在C++17中,它强制执行了一些副本省略(。
但是,如果未进行返回值优化,则通常会自动移动返回值。return
语句有特殊的行为,如果操作数直接命名具有类似条件的变量,则将执行重载解析,就好像返回值初始值设定项是一个右值表达式一样(即使它不是(,因此将考虑移动构造函数。无论return
语句中引用的变量的类型是否与返回类型相同,都会执行此自动移动,因此它也适用于您的示例。
不需要显式使用std::move
,而且在某些情况下(尽管不是您的具体情况(,这是一种令人讨厌的做法,如上所述。所以只需使用:
std::optional<std::vector<int>> getVectOr(int i) {
if(i==1) {
std::vector<int> v = makeVector();
return v;
}
else if(i==2) {
std::vector<int> v2 = makeVector2();
return v2;
}
return std::nullopt;
}
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 如何将不可移动和不可复制的函数返回值获取到数组中
- 复制省略并在返回值中移动语义
- 当设置对象等于另一个函数的返回值时,为什么要调用移动构造函数/分配
- 通过从函数返回值移动进行大括号初始化会产生"excess elements"错误
- 从具有移动语义或返回值优化的函数返回值,但不返回复制构造函数
- 关于从函数和移动返回大值的混淆
- 从移动返回的右值引用未持久化
- c++11返回值优化或移动
- 将对以字符串形式返回文件内容的函数执行移动语义优化或返回值优化,我会从中受益吗
- 类挂钩-移动基板返回值
- 从技术上讲,如何在不复制的情况下移动函数返回值
- 移动或命名返回值优化(NRVO)