Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move Semantics for POD-ish types

Is there any point implementing a move constructor and move assignment operator for a struct or class that contains only primitive types? For instance,

struct Foo
{
    float x;
    float y;
    float z;

    /// ... ctor, copy ctor, assignment overload, etc...


};

I can see that, if I had something more complex, like:

struct Bar
{
    float x,y,z;
    std::string Name;
};  

where I'd rather move Name than copy it, a move ctor would make sense. However, "moving" a float doesn't (semantically) make sense to me.

Thoughts?

like image 762
3Dave Avatar asked Feb 26 '14 17:02

3Dave


People also ask

What is Move semantics in C++?

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.

Does rust have move semantics?

Move semantics in Rust In Rust, all types are movable, and all move operations amount to a bit copy of the original data to its new location. Unlike C++, moving is the default operation, and we explicitly have to call a function to copy them.

What are move constructors?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class, MemoryBlock , which manages a memory buffer.

Does STD swap use move semantics?

Using std::move wherever we can, as shown in the swap function above, gives us the following important benefits: For those types that implement move semantics, many standard algorithms and operations will use move semantics and thus experience a potentially significant performance gain.


2 Answers

Note that a fully conforming C++11/14 compiler (not current version of VS2013) should automatically generate move operations for your Bar struct:

struct Bar
{
    float x,y,z;
    std::string Name;
};

In general, you should write move operations explicitly only for direct resource managers, that act like "building blocks". When you assemble together building blocks in more complex classes, the compiler should automatically generate move operations (using member-wise moves).

like image 141
Mr.C64 Avatar answered Nov 19 '22 17:11

Mr.C64


Even if you have that std::string member, it doesn't make sense to implement a move constructor. The implicit move constructor will already move each of the members, which in the case of float will just copy it, and in the case of std::string will move it.

You should only really need to provide a move constructor when your class is doing some of its own memory management. That is, if you're allocating memory in the constructor, then you'll want to transfer the pointer to that allocated memory during a move. See the Rule of Five.

It's possible to avoid this situation entirely if you always rely on smart pointers to handle your allocated memory for you. See the Rule of Zero.

like image 21
Joseph Mansfield Avatar answered Nov 19 '22 15:11

Joseph Mansfield