Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always use std::move in a constructor?

Are the move semantics used in Example A necessary, and which struct is superior?

Example A:

struct A
{
    std::string a;
    A( std::string a ) : a( std::move(a) ){ }
};

Example B:

struct B
{
    std::string b;
    B( const std::string& b ) : b( b ){ }
};

I don't believe this is a duplicate question. I am asking specifically which example is superior from the perspective of using member initialization in a class constructor. None of the examples or answers listed in the other question dealt with member initialization.

I don't like that the constructor is called with a reference parameter, then copied into the member. It seems that it could be wasteful to have multiple copy operations.

I want to "pipe" the data into the members as efficiently as possible but I don't want to take rvalues as the constructor parameters.

like image 678
Dustin Nieffenegger Avatar asked Apr 04 '17 01:04

Dustin Nieffenegger


People also ask

When should we use 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.

Why is move better than COPY C++?

Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.

Why move constructor is faster than copy constructor?

It's faster because moving allows the source to be left in a invalid state, so you can steal it's resources. For example, if a object holds a pointer to a large block of allocated memory, a move can simply steal the pointer while a copy must allocate its own memory and copy the whole memory block.

Are move constructors 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.


1 Answers

Struct A is superior.

Moving an object is usually very cheap (and can often be completely optimized out), so typically one shouldn't care about the number of moves. But it's important to minimize the number of copies. The number of copies in example A is equal to or less than the number of copies in example B.

More specifically, A and B are equivalent if the original string is an L-value:

std::string s;
...
A a(s);  // one copy
B b(s);  // one copy

but A is better when the original string is an R-value:

std::string MakeString();
...
A a(MakeString());  // zero copies
B b(MakeString());  // one copy
like image 133
Andrei Matveiakin Avatar answered Sep 28 '22 04:09

Andrei Matveiakin