当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - Difference between auto&& and auto

问题描述:

So, I've made such a class, and launched 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;

}

And what I've got really suprised me:

constructor

inside fun1

constructor

inside fun2

move constructor

constructor

inside fun1

move constructor

constructor

inside fun2

move constructor

Why when the "testing_var3" is returned by fun1, the move constructor is used? Why there is such a difference, when the deduction of type is made by auto not 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?

/EDIT:

I've added some extra code to constructors and destructors. Now I get:

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

And my next question is: Why the first variable is dangling reference and other don't? Why second variable isn't such a reference, as suggested @MattMcNabb ?

网友答案:

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

testing_var3 is deduced as type my_class, therefore a constructor must be called to create a new my_class object. Since the right hand side is a temporary, the move constructor is chosen.

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

If you use auto&& then you always declare a reference, and a constructor is not called when a reference to class is bound to an expression of the same class type, because no new object is created. auto never declares a reference.

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?

There is no assignment occurring; just copy-initialization. In

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

assignment operators are not called, despite the appearance of the = token. It's initialization, not assignment. Assignment requires an already-constructed object to assign to.

网友答案:

testing_var3 is constructed by move ctor and for the last the return value is constructed by a move ctor...

There is no assignment in fun2 only a returned value that need to be constructed/initialized.

网友答案:

I would recommend you read Scott Meyers' blog on "Universal References". auto&& can bind to an lvalue or an rvalue. In most situations, you won't need to use auto&&, unless you really know what you are doing.

分享给朋友:
您可能感兴趣的文章:
随机阅读: