Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ move semantics clarification

Tags:

c++

c++11

I have a Text class that contain a std::string. A method SetText as follow :

void Text::SetText( const std::string& str )
{
    m_str = str;
}

Since this method will almost always been called with rvalues as parameter, I thought about move constructors. I understand the basics, but that's all. So I made tests and came to the conclusion that another function like that would be better, and once the move constructor and move assignement were defined, there could be performance gains :

void Text::SetText( std::string&& str )
{
    m_str = move( str );
}

There are my questions :

  • Does it works with std container? Does they provide move constructor and assignements?
  • Is move semantics usefull when there is not heap allocations is the class ? ( I mean no heap allocation at all, so no smart pointers as class member )

Thanks.

like image 834
Aulaulz Avatar asked Mar 19 '23 21:03

Aulaulz


1 Answers

Your code is correct. But the preferred C++11 approach is:

void Text::SetText(std::string str)
{
    m_str = move(str);
}

That is, pass by value and move from it.

This will do to moves if you pass an rvalue and one copy and one move if you pass an lvalue where in the later case the one copy is necessary.

Does it works with std container? Does they provide move constructor and assignements?

Yes, standard library provides move constructors and move assignments for all classes where it can be made more efficient than copy.

Is move semantics usefull when there is not heap allocations is the class ? ( I mean no heap allocation at all, so no smart pointers as class member )

Except a few cases with other kinds of resources, no.

If all data of the object is stored directly in the object, they have to be copied and there is no other work that could be saved by moving.

Also note that if you make the function inline, compiler should be able to elide one of the moves in the rvalue case. It won't be able to elide it in the lvalue case unless the operator= is also inlined, because it won't be allowed to replace the moving assignment with copying assignment.

like image 72
Jan Hudec Avatar answered Mar 28 '23 11:03

Jan Hudec