11

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?

3Dave
  • 28,657
  • 18
  • 88
  • 151
  • Regardless of whether a move constructor makes sense at all, why implement it when the compiler can generate a perfectly good one for you? –  Feb 26 '14 at 17:23
  • @DavidLively, in general, if there's no pointers, moving makes no sense. Since `std::string` uses pointers, it benefits from move. – Mooing Duck Feb 26 '14 at 17:24
  • 1
    Even in the second one, it doesn't make much sense to implement a move constructor. It already works as is. – R. Martinho Fernandes Feb 26 '14 at 17:26
  • This is covered in [the FAQ](http://stackoverflow.com/questions/3106110/), search for `cannot_benefit_from_move_semantics`. – fredoverflow Feb 26 '14 at 17:30
  • Yeah, the string isn't the best example. – 3Dave Feb 26 '14 at 17:52

3 Answers3

6

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.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
4

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).

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
2

No need for that. If there are only primitive types in a class/struct, then default constructor/assignment operator will actually do that.

Borzh
  • 5,069
  • 2
  • 48
  • 64