Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does calling std::move on a const object call the copy constructor when passed to another object?

Tags:

Why does calling std::move on a const object call the copy constructor when passed to another object? Specifically, the code

#include <iostream>  struct Foo {     Foo() = default;     Foo(Foo && x) { std::cout << "Move" << std::endl; }     Foo(Foo const & x) = delete; };  int main() {     Foo const x; Foo y(std::move(x));  } 

fails to compile with the message:

g++ -std=c++14 test07.cpp -o test07 test07.cpp: In function 'int main()': test07.cpp:10:36: error: use of deleted function 'Foo::Foo(const Foo&)'      Foo const x; Foo y(std::move(x));                                      ^ test07.cpp:6:5: note: declared here      Foo(Foo const & x) = delete;      ^ Makefile:2: recipe for target 'all' failed make: *** [all] Error 1 

Certainly, I expect it to fail because we can't move a const value. At the same time, I don't understand the route that the code takes before it tries to call the copy constructor. Meaning, I know that std::move converts the element to an x-value, but I don't know how things proceed after that with respect to const.

like image 269
wyer33 Avatar asked Jan 07 '15 02:01

wyer33


People also ask

What is the purpose of std :: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

Does std :: move make a copy?

std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.

When you passed object to a copy constructor then it?

If an object is passed as value to the Copy Constructor then its copy constructor would call itself, to copy the actual parameter to the formal parameter. Thus an endless chain of call to the copy constructor will be initiated.

Why copy constructor is called when we pass an object as an argument?

Because passing by value to a function means the function has its own copy of the object. To this end, the copy constructor is called.


1 Answers

The type of the result of calling std::move with a T const argument is T const&&, which cannot bind to a T&& parameter. The next best match is your copy constructor, which is deleted, hence the error.

Explicitly deleteing a function doesn't mean it is not available for overload resolution, but that if it is indeed the most viable candidate selected by overload resolution, then it's a compiler error.

The result makes sense because a move construction is an operation that steals resources from the source object, thus mutating it, so you shouldn't be able to do that to a const object simply by calling std::move.

like image 129
Praetorian Avatar answered Oct 22 '22 01:10

Praetorian