auto&&和auto的区别

Difference between auto&& and auto

所以,我做了这样一个 class,并启动了 main:

class my_class{
public:
    my_class(): status("constructor"){
        cout << "constructor" << endl;
    }
    my_class(my_class&& obj): status("move constructor"){
        cout << "move constructor" << endl;
    }
    my_class(const my_class& obj): status("copy constructor"){
        cout << "copy constructor" << endl;
    }
    my_class& operator=(my_class&& obj){
        cout << "move assignment" << endl;
        return *this;
    }
    my_class& operator=(const my_class& obj){
        cout << "copy assignment" << endl;
        return *this;
    }
    ~my_class(){
        cout << "destructor; " << "object made by: " << status << endl;
    }
    string status;
};

my_class&& fun1(my_class&& temp){
    cout << "inside fun1" << endl;
    return move(temp);
}

my_class fun2(my_class&& temp){
    cout << "inside fun2" << endl;
    return move(temp);
}

int main(){
    auto&& testing_var1 = fun1(my_class{});
    auto&& testing_var2 = fun2(my_class{});
    auto testing_var3 = fun1(my_class{});
    auto testing_var4 = fun2(my_class{});
    return 0;
}

我得到的东西真的让我吃惊:

constructor
inside fun1
constructor
inside fun2
move constructor
constructor
inside fun1
move constructor
constructor
inside fun2
move constructor

为什么fun1返回"testing_var3"时,使用了move构造函数?类型的推导是auto而不是auto&&,为什么会有这样的差异?

我以为会使用移动赋值,但 fun1 中的移动构造函数对我来说是胡说八道...

为什么在fun2中使用移动构造函数?不应该是移动作业吗?

/编辑:

我在构造函数和析构函数中添加了一些额外的代码。现在我得到:

constructor
inside fun1
destructor; object made by: constructor
constructor
inside fun2
move constructor
destructor; object made by: constructor
constructor
inside fun1
move constructor
destructor; object made by: constructor
constructor
inside fun2
move constructor
destructor; object made by: constructor
destructor; object made by: move constructor
destructor; object made by: move constructor
destructor; object made by: move constructor

我的下一个问题是:为什么第一个变量是悬挂引用而其他变量不是?为什么第二个变量不是像@MattMcNabb 所建议的那样的引用?

Why when the "testing_var3" is returned by fun1, the move constructor is used?

testing_var3 被推导为 my_class 类型,因此必须调用构造函数来创建新的 my_class 对象。由于右侧是临时的,因此选择移动构造函数。

Why there is such a difference, when the deduction of type is made by auto not auto&&?

如果你使用 auto&& 那么你总是声明一个引用,并且当对 class 的引用绑定到相同 class 类型的表达式时不会调用构造函数,因为没有创建新对象。 auto 从不声明引用。

I thought that move assignment would be used, but move constructor in fun1 is for me nonsense...

And why the move constructor is used in fun2? Shouldn't it be move assignment?

没有分配发生;只是 复制初始化 。在

T x = e;
T x = braced-init-list;

不调用赋值运算符,尽管出现了 = 标记。是初始化,不是赋值。赋值需要一个已经构造好的对象来赋值。

testing_var3 由 move ctor 构造,最后 return 值由 move ctor 构造...

fun2 中没有赋值,只有 returned 值需要 constructed/initialized。

我建议您在 "Universal References" 上阅读 Scott Meyers 的 blog。 auto&& 可以绑定到左值或右值。在大多数情况下,您不需要使用 auto&&,除非您真的知道自己在做什么。