Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当变量为右值引用时,自动从局部变量移动_C++_C++20 - Fatal编程技术网

C++ 当变量为右值引用时,自动从局部变量移动

C++ 当变量为右值引用时,自动从局部变量移动,c++,c++20,C++,C++20,根据cppreference,在return语句中,本地右值引用应该从C++20中移动: 从局部变量和参数自动移动 If表达式是一个id表达式(可能带括号),它命名类型为 非易失性对象类型或 对对象类型的非易失性右值引用 (从C++20开始) 我试过第二个要点(): #包括 结构Foo{}; 结构条{ Bar()=默认值; 酒吧(常富&){ printf(“副本!\n”); } 酒吧(Foo&){ printf(“移动!\n”); } }; 巴富(){ 福福; Foo&&rf=静态

根据cppreference,在return语句中,本地右值引用应该从C++20中移动:

从局部变量和参数自动移动

  • 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])或
    co­return
    ([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();
}