C++ 当变量为右值引用时,自动从局部变量移动
根据cppreference,在return语句中,本地右值引用应该从C++20中移动: 从局部变量和参数自动移动C++ 当变量为右值引用时,自动从局部变量移动,c++,c++20,C++,C++20,根据cppreference,在return语句中,本地右值引用应该从C++20中移动: 从局部变量和参数自动移动 If表达式是一个id表达式(可能带括号),它命名类型为 非易失性对象类型或 对对象类型的非易失性右值引用 (从C++20开始) 我试过第二个要点(): #包括 结构Foo{}; 结构条{ Bar()=默认值; 酒吧(常富&){ printf(“副本!\n”); } 酒吧(Foo&){ printf(“移动!\n”); } }; 巴富(){ 福福; Foo&&rf=静态
- If表达式是一个id表达式(可能带括号),它命名类型为
- 非易失性对象类型或 对对象类型的非易失性右值引用 (从C++20开始)
#包括
结构Foo{};
结构条{
Bar()=默认值;
酒吧(常富&){
printf(“副本!\n”);
}
酒吧(Foo&){
printf(“移动!\n”);
}
};
巴富(){
福福;
Foo&&rf=静态施法(f);
返回射频;
}
int main(){
foo();
}
我希望这个程序打印move代码>。但实际上,clang和gcc都打印copy代码>。这是不是还没有在编译器中实现的东西?还是我误解了什么
这是不是还没有在编译器中实现的东西
(查找P1825),您正确理解了规则。但是让我们来看看,确定一下。此处的具体标准文本位于:
隐式可移动实体是自动存储持续时间的变量,它是非易失性对象或对非易失性对象类型的右值引用。在以下复制初始化上下文中,可以使用移动操作代替复制操作:
- 如果
return
([stmt.return])或coreturn
([stmt.return.coroutine])语句中的表达式是一个id表达式(可能带括号),它命名了在体或最里面的封闭函数或lambda表达式的参数声明子句中声明的隐式可移动实体,或
- 如果抛出表达式的操作数是[…]
rf
是对Foo
(非易失性对象类型,check)的右值引用(check),使其成为隐式可移动的实体。在中返回rf代码>,这是一个id表达式,用于命名函数体(check)中声明的隐式可移动实体(check)。所以,我们移动而不是复制 在本例中使用2个类的目的是什么?@DanielLangr:no避免NRVO。请检查,自19.24版本以来,它仅在MSVC上可用-DR:Implicit move可用于更多本地对象和右值引用。@rafix07这基本上是一个答案。@rafix07:谢谢,很高兴了解该表!
#include <cstdio>
struct Foo {};
struct Bar {
Bar() = default;
Bar(const Foo &) {
printf("copy!\n");
}
Bar(Foo &&) {
printf("move!\n");
}
};
Bar foo() {
Foo f;
Foo &&rf = static_cast<Foo &&>(f);
return rf;
}
int main() {
foo();
}