为什么自动移动不能使用 return 来自右值引用输入的值的函数?

Why doesn't automatic move work with function which return the value from rvalue reference input?

我已经知道自动移动无法使用 return 来自 Rvalue Reference 输入的值的功能。但是为什么?

下面是自动移动不起作用的示例代码。

Widget makeWidget(Widget&& w) {
  ....
  return w; // Compiler copies w. not move it.
}

如果函数输入是按值复制,则自动移动有效。

Widget makeWidget(Widget w) {
  ....
  return w; // Compiler moves w. not copy it.
}

从 C++20 开始,代码应该可以像您预期的那样工作; returning 局部变量和参数时执行自动移动操作,它也适用于右值引用 (C++20 起)。

If expression is a (possibly parenthesized) id-expression that names a variable whose type is either

  • a non-volatile object type or
  • a non-volatile rvalue reference to object type (since C++20)

LIVE

C++17标准的相关部分[class.copy.elision/3]:

In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

  • If the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function...

这不适用于:

Widget makeWidget(Widget&& w)
{
  return w;
}

因为 w 没有命名具有自动存储持续时间的对象(在函数内)。

在C++20中,情况is different:

An implicitly movable entity is a variable of automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type. In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

  • If the expression in a return or co_­return statement is a (possibly parenthesized) id-expression that names an implicitly movable entity declared in the body or parameter-declaration-clause of the innermost enclosing function...

此处,引用 w 满足这些要求,因为它是在参数声明子句中声明的右值引用。

为什么直到 C++20 才出现同样的情况?我不能说;之前可能没有人提出过这样的改变。