c++ - 这如何与返回值优化一起使用?

标签 c++

vector<int> f(const vector<int>& v)
{
    vector<int> ret(v.size());
    fill(ret.begin(), ret.end(), 123);
    copy(v.begin(), v.end(), ret.begin());
    return ret;
}

int main()
{
    vector<int> v(10);
    v = f(v);
}

如果将返回值优化应用于 f,则局部变量 ret 与 main 中的 v 共享相同的地址。但如果这是真的,填充 ret 将在复制之前丢弃 v 中的数据。没有 RVO 的代码是正确的,优化不应破坏行为。

这安全吗,还是我没有正确理解 RVO?

最佳答案

这是怎么回事:

在调用者这边,提供了一个可以保存结果的返回槽,这意味着调用者为类型为std::vector<int>的变量提供了内存。 .它期望被调用的方法构造值,并负责在结果不再使用时调用析构函数并释放内存(如有必要,它可能只存在于堆栈中)。

如果没有 NRVO,被调用函数(可能存在于不同的翻译单元中!)会这样:

  • ret提供内存插槽.
  • 构造局部变量ret在这个内存插槽中。
  • 做事...
  • 通过复制 ret 在提供的内存槽中复制构造返回值.
  • 调用ret的析构函数。

现在,有了 NRVO,可以在被调用函数的翻译单元中做出优化的决定。它将上面的转换为:

  • 构造 ret在方法返回槽的内存中。
  • 做事...

不需要做任何其他事情,因为内存是自己的,析构函数是由调用者调用的,因为优化对调用者是透明的:)

当然,这不能消除对 v 的赋值。在你的例子中。如果您将结果存储在不同的变量中,例如

std::vector<int> w = f(v);

NRVO 将 build ret直接进入w的内存(因为这将作为返回槽传递给 f )。

关于c++ - 这如何与返回值优化一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18662476/

相关文章:

java - C++ 中的 NULL 和 Java 中的 null 有什么区别?

c++ - Qt - 在 Windows 上按下 Alt 后防止菜单栏获取焦点

c++ - 在 QML BB10 中的 map 位置上添加 Pin

c++ - PKEY_EdgeGesture_DisableTouchWhenFullscreen 未声明的标识符

java - 如何使用 ByteBuffer 查看 header 偏移量来制作字节数组?

c++ - 如何将 std::basic_string 类型转换为 char 类型的数组?

c++ - 是否可以通过一个函数调用将统一数据发送到GLSL中的结构

c++ - 无法使用 gprof 累积时间 - gnu 分析器

c++ - 在函数中分配内存以返回给用户

c++ - gdb 中 C++ 引用修改的硬件断点