复制省略并在返回值中移动语义

Copy elision and move semantic in return value

本文关键字:移动 语义 返回值 复制省      更新时间:2023-10-16

Background.

我曾经写过C++代码,现在我又开始了。我正在阅读一些涵盖 c++11(及更高(功能的书籍。关于堆栈溢出也有许多复杂的答案,但我只需要一个简单的答案。

在处理指针时,我曾经遵循著名的三法则,但现在我看到有新的移动语义,因此该规则已重命名为五法则。在网上阅读,我看到C++已经进化了,现在也有复制省略。我现在有很多新概念。看看这个:

struct Test {};
auto getNewTest() { return Test(); }
auto x = getNewTest();

在这种情况下(假设启用了复制 elision(,发生的唯一副本应该是当我将值断言为x时(只有 1 个副本(。以前会有 2 个副本:1 个作为返回值,1 个作为 x 值。

到目前为止一切顺利,但使用移动语义我可以实现相同的目标(如果我是对的(!假设 Test 已正确分配移动操作;我可以称之为:

auto getNewTest() { return Test(); }
auto x = std::move(getNewTest());

问题

我已经明白,当我必须摆脱旧变量并且我可以将其所有内容移动到新变量中时,移动是好的,而不是将其复制到新变量中。

碰巧我有一个像return SomeClass(1,2,3)这样的陈述,我想避免太多副本。std::move((是否执行零副本?因为复制 elision 避免了 1 个副本(返回值(,并且由于复制构造函数而只执行 1 个副本。

我的猜测是,使用 std::move(( 我窃取了从函数创建的对象,所以我有零副本。我说的对吗?总的来说,这可能是平庸的,但对我来说花了很多时间。

你想太多了。 使用编写的代码,

auto x = getNewTest();

实际上构造x到位,这几乎是你能得到的效率。

这种行为在 C++17 中得到了保证,但在实践中,它已经以这种方式工作了很长时间。

更多 这里. 我不能太推荐cpp偏好,尽管它不是权威的。