C++ 在技术上如何在没有拷贝的情况下 move 函数返回值?

标签 c++ move

当一个函数返回一个值时,它被放入堆栈(函数堆栈帧被删除,但返回值保留在那里直到调用者获取它)。

如果返回值在堆栈上, move 如何在不将其复制到变量内存位置的情况下获取该值?

例如在这段代码中:

A a = getA();

最佳答案

在许多 C++ 实现中,返回“复杂”数据类型的函数被传递一个隐藏参数,该参数是指向返回实例所在空间的指针。本质上,编译器将 Foo r = fun(); 变成了

char alignas(Foo) r[sizeof Foo]; // Foo-sized buffer, unitialized!
fun(&r);

如您所见,Foo 分配在调用者帧的堆栈上。现在,在 fun 的实现中可能有一个拷贝。施工

Foo fun() {
  Foo rv;
  ...
  return rv;
}

一般实现为

void fun(Foo * $ret) {
  Foo rv;
  ..
  new ($ret) Foo(rv); // copy construction
}

当应用返回值优化时,这将更改为

void fun(Foo * $ret) {
  Foo & rv = *(new ($ret) Foo);
  ...
  return;
}

现在不涉及复制。这是对实现如何做到这一点的高度概述。

关于C++ 在技术上如何在没有拷贝的情况下 move 函数返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24510449/

相关文章:

带有可变参数 std::function 的 C++11 函数签名

c++ - 如何构建一个元组 vector 并像对一样对它们进行排序?

c++ - Visual Studio 和在 C++ 中使用类工厂自动创建对象

包含内容的文件夹上的 Java renameTo

c++ - 是否可以 std::move 本地堆栈变量?

function - 在 Rust 中实际需要 move 到函数的情况

c++ - 基于范围的 for 循环和 ADL

c++ - 使用 sscanf 定位错误的来源

c++ - std::pair assignment with downcast

c# - 平滑鼠标 move