c++11: how to understand the function move

与世无争的帅哥 提交于 2019-12-11 01:08:04

问题


I can't understand the function move in c++11.

From here, I got things below:

Although note that -in the standard library- moving implies that the moved-from object is left in a valid but unspecified state. Which means that, after such an operation, the value of the moved-from object should only be destroyed or assigned a new value; accessing it otherwise yields an unspecified value.

In my opinion, after move(), the moved-from object has been "clear". However, I've done a test below:

std::string str = "abcd";
std::move(str);
std::cout<<str;

I got abcd on my screen.
So has the str been destroyed? If so, I could get abcd because I'm just lucky? Or I misunderstood the function move?

Besides, when I read C++ Primer, I got such a code:

class Base{/* ... */};
class D: public Base{
public:
    D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
};

I'm confused now. If the function move will clear the object, the parameter d will be clear, how could we "use d to initialize the members of D"?


回答1:


std::move doesn’t move anything. std::move is merely a function template that perform casts. std::move unconditionally casts its argument to an rvalue,

std::move(str);

With this expression you are just doing type cast from lvalue to rvalue.

small modification in program to understand better.

 std::string str = "abcd";
 std::string str1 = std::move(str);
 std::cout<<str<<std::endl;
 std::cout<<str1<<std::endl; 

str lvalue typecast to rvalue by std::move, std::string = std::move(str); =>this expression call the string move constructor where actual stealing of resources take placed. str resources(abcd) are steeled and printed empty string.

Here is sample implementation of move function. Please note that it is not complete implementation of standard library.

template<typename T> // C++14; still in
decltype(auto) move(T&& param) // namespace std
{
using ReturnType = remove_reference_t<T>&&;
return static_cast<ReturnType>(param);
}

Applying std::move to an object tells the compiler that the object is eligible to be moved from. It cast to the rvalue.

class Base{/* ... */};
class D: public Base{
public:
    D(D&& d): Base(std::move(d)){/* use d to initialize the members of D */}
};

Base(std::move(d)) it will do up-casting only move the base class part only.

Here one more interesting thing to learn for you. If you do not invoke base class destructor with std::move like D(D&& d): Base(d) then d will be considered as lvalue and copy constructor of Base class involved instead of move constructor. Refer for more detail Move constructor on derived object




回答2:


std::move doesn't actually do anything. It's roughly analogous to a cast expression, in that the return value is the original object, but treated differently.

More precisely, std::move returns the object in a form which is amenable to its resources being 'stolen' for some other purpose. The original object remains valid, more or less (you're only supposed to do certain special things to it, though that's primarily a matter of convention and not necessarily applicable to non-standard-library objects), but the stolen-away resources no longer belong to it, and generally won't be referenced by it any more.

But! std::move doesn't, itself, do the stealing. It just sets things up for stealing to be allowed. Since you're not doing anything with the result, let alone something which could take advantage of the opportunity, nothing gets stolen.



来源:https://stackoverflow.com/questions/36002627/c11-how-to-understand-the-function-move

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!