Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do built-in types have move semantics?

Consider this code:

#include <iostream> using namespace std;  void Func(int&& i) {     ++i; }  int main() {     int num = 1234;     cout << "Before: " << num << endl;     Func(std::move(num));     cout << "After: " << num << endl; } 

Its output is:

Before: 1234 After: 1235 

Clearly, i is being modified inside Func, as it is bound to parameter i after being "converted" to an r-value reference by std::move.

Well, my point:

Moving an object means transferring ownership of resources from one object into another. However, built-in types holds no resources because they themselves are the resources. It makes no sense to transfer the resources they hold. As shown by the example, num's value is modified. Its resource, its self, is the one being modified.

Do built-in types have move semantics?

Also, Do built-in type objects after it is moved (if it is) a well-defined behavior?

like image 694
Mark Garcia Avatar asked Feb 04 '13 02:02

Mark Garcia


People also ask

What's the need to move semantics?

Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.

How are Move Semantics implemented?

Move semantics aim to avoid the copying of data from temporary objects by instead stealing the memory location of where the object resides. This behaviour is implemented through the use of a move constructor and move assignment operator that act only on rvalue references.

Does STD swap use move semantics?

Is specializing std::swap deprecated now that we have move semantics? No. This is the generic version, but you can optimize it to skip a third move operation.

Are move constructor automatically generated?

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.


Video Answer


1 Answers

And so, is the one shown by the example a well-defined behavior?

Yes, the behaviour shown in the example is the only behaviour allowed by the standard. That is because std::move doesn't move. The things that move are move constructors and move assignment operators.

All std::move does is change an lvalue into an xvalue, so that it can bind to rvalue references. It does not invoke any constructor or anything else. Changing the value category happens at the type level. Nothing happens at runtime.

Rvalue references are still references: they refer to the original object. The function increments the original integer through the reference given.

If a function takes an argument by reference, no copies nor moves happen: the original object is bound to the reference.

If a function takes an argument by value, then we might have a move.

However, fundamental types don't have move constructors. Moves degrade to copies in that case.

like image 188
R. Martinho Fernandes Avatar answered Sep 22 '22 05:09

R. Martinho Fernandes