C++11 C++;11return语句中左值引用的移动语义

C++11 C++;11return语句中左值引用的移动语义,c++11,move-semantics,C++11,Move Semantics,在C++11/14中,我们有:返回值优化,移动语义,一些类,比如没有复制构造函数 问题1:当DECLARE_COPY_CTOR等于1或等于零时,下面的代码段的正确行为是什么 问题2:使用MSVC 2013为以下Win32调试版本中的代码片段构建的控制台应用程序在控制台中提供了:A(),A(A&&),~A(),~A()。看起来左值引用“a”被用来绑定到“a&&”。这合法吗?我认为只有临时对象可以作为移动的候选对象 问题3:在发行版中,构建编译器选择使用Rvo(所以输出是:A(),~A()) 编译器

在C++11/14中,我们有:返回值优化,移动语义,一些类,比如没有复制构造函数

问题1:当DECLARE_COPY_CTOR等于1或等于零时,下面的代码段的正确行为是什么

问题2:使用MSVC 2013为以下Win32调试版本中的代码片段构建的控制台应用程序在控制台中提供了:A(),A(A&&),~A(),~A()。看起来左值引用“a”被用来绑定到“a&&”。这合法吗?我认为只有临时对象可以作为移动的候选对象

问题3:在发行版中,构建编译器选择使用Rvo(所以输出是:A(),~A())

编译器是否可以自由选择函数范围中的“a”是否为移动的canditate

#include <stdio.h>
#include <iostream>
#include <memory>

#define DECLARE_COPY_CTOR 0

class A
{
public:
    A() {puts("A()");}
    ~A() { puts("~A()"); }

#if DECLARE_COPY_CTOR
    A(A&) { puts("A(A&)"); }
#endif

    A(A&&) { puts("A(A&&)"); }
    A& operator = (A&) { puts("A& operator = (A&)"); return *this; }
};

A F()
{
    A a;       // here a is lvalue
    return a;  // here a is still lvalue
}

int main()
{
    auto i = F();
    return 0;
}
#包括
#包括
#包括
#定义DECLARE\u COPY\u CTOR 0
甲级
{
公众:
A(){puts(“A()”);}
~A(){put(“~A()”);}
#如果声明复制
A(A&){puts(“A(A&”);}
#恩迪夫
A(A&&){put(A(A&);}
A&operator=(A&){put(“A&operator=(A&”);返回*this;}
};
A F()
{
A;//这里A是左值
返回a;//这里a仍然是左值
}
int main()
{
自动i=F();
返回0;
}
问题1。当DECLARE_COPY_CTOR等于1或等于零时,下面的代码段的正确行为是什么

DECLARE\u COPY\u CTOR
对行为没有影响。程序中未调用复制构造函数

问题2。看起来像左值引用“a”

a
是左值,但它不是左值引用

问题2。这合法吗

是的,返回不可复制的本地左值是合法的。它将被移动

第三季度。编译器是否可以自由选择函数范围中的“a”是否为移动的canditate

#include <stdio.h>
#include <iostream>
#include <memory>

#define DECLARE_COPY_CTOR 0

class A
{
public:
    A() {puts("A()");}
    ~A() { puts("~A()"); }

#if DECLARE_COPY_CTOR
    A(A&) { puts("A(A&)"); }
#endif

    A(A&&) { puts("A(A&&)"); }
    A& operator = (A&) { puts("A& operator = (A&)"); return *this; }
};

A F()
{
    A a;       // here a is lvalue
    return a;  // here a is still lvalue
}

int main()
{
    auto i = F();
    return 0;
}
如果返回的局部变量类型是可移动的,则必须移动而不是复制它。NRVO适用于这种情况,因此编译器可以自由删除移动,就像在c++11之前可以自由删除副本一样

问题1。当DECLARE_COPY_CTOR等于1或等于零时,下面的代码段的正确行为是什么

DECLARE\u COPY\u CTOR
对行为没有影响。程序中未调用复制构造函数

问题2。看起来像左值引用“a”

a
是左值,但它不是左值引用

问题2。这合法吗

是的,返回不可复制的本地左值是合法的。它将被移动

第三季度。编译器是否可以自由选择函数范围中的“a”是否为移动的canditate

#include <stdio.h>
#include <iostream>
#include <memory>

#define DECLARE_COPY_CTOR 0

class A
{
public:
    A() {puts("A()");}
    ~A() { puts("~A()"); }

#if DECLARE_COPY_CTOR
    A(A&) { puts("A(A&)"); }
#endif

    A(A&&) { puts("A(A&&)"); }
    A& operator = (A&) { puts("A& operator = (A&)"); return *this; }
};

A F()
{
    A a;       // here a is lvalue
    return a;  // here a is still lvalue
}

int main()
{
    auto i = F();
    return 0;
}
如果返回的局部变量类型是可移动的,则必须移动而不是复制它。NRVO适用于这种情况,因此编译器可以自由删除移动,就像在c++11之前可以自由删除副本一样