为什么自动移动不能使用 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)
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 才出现同样的情况?我不能说;之前可能没有人提出过这样的改变。
我已经知道自动移动无法使用 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)
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
orco_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 才出现同样的情况?我不能说;之前可能没有人提出过这样的改变。