2

What is the correct way of using or creating a move constructor?

Here is an example:

class Example
{
public:
    Example( int && p_Number,
             bool && p_YesNo,
             std::string && p_String ) : // Error here
             Number( p_Number ),
             YesNo( p_YesNo ),
             String( p_String )
    {
    };

private:
    int Number;
    bool YesNo;
    std::string String;
    std::vector< unsigned char > Vector;
};

void ShowExample( void )
{
    Example ExampleA( 2013,
                      true,
                      "HelloWorld" // Why won't it work?
                      );
};

I've shown the errors in the comment.

Edit: *Okay, I am now sure what I have is not a move constructor. So, can I write one?*

11
  • 1
    You should show the specific error, not your comment on the error. "HelloWorld" is const. Are you accounting for this? Commented Mar 2, 2013 at 0:33
  • 1
    "HelloWorld" // Why won't it work? If you're using VC++ 2010, it's because of a bug (fixed in VC++ 2012). Commented Mar 2, 2013 at 0:34
  • 3
    You'd say String(std::move(p_String)) etc. But what you have is not the "move constructor". I'd rather call "a moving constructor". Commented Mar 2, 2013 at 0:35
  • 1
    @user2117427 there can be only one move constructor per class: className(className&&) just like there is only one copy constructor per class: className(const className&) but you still can have constructors that accept rvalues (ie. move semantics) on specific arguments. It's just a name issue. Commented Mar 2, 2013 at 0:38
  • 3
    @syam, you always need to say String(std::move(p_String)) to move it, because p_String is not an rvalue Commented Mar 2, 2013 at 0:48

2 Answers 2

11

First of all, there is no reason to write a move constructor for that class. The compiler generated one will do just fine. But if you were to write it, it might look something like this:

Example(Example && rhs)
    :Number(rhs.Number)
    ,YesNo(rhs.YesNo)
    ,String(std::move(rhs.String))
    ,Vector(std::move(rhs.Vector))
{}

You can, if you want, for consistency, call std::move on the int and the bool, but you won't gain anything from it.

For that other constructor, with all the arguments, the simplest thing to do is this:

Example(int p_Number, bool p_YesNo, std::string p_String)
    :Number(p_Number)
    ,YesNo(p_YesNo)
    ,String(std::move(p_String))
{}

In response to your comment below:

A move constructor is invoked whenever you try to construct an object with an R-value of the same type as the only constructor argument. For example, when an object is returned by value from a function, that is an R-value, although often in that case, copying and moving is skipped altogether. A case where you can create an R-value is by calling std::move on an L-value. For example:

Example ex1(7, true, "Cheese"); // ex1 is an L-value
Example ex2(std::move(ex1));    // moves constructs ex2 with ex1
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I can understand that there is really no point of using a move constructor for the example class. But its an example. I have a question. How would I declare an object that will be using the move constructor?
5

A move constructor takes an rvalue reference to another object of the same type, and moves the other object's resources to the new object, for example:

Example(Example && other) :
    Number(other.Number),             // no point in moving primitive types
    YesNo(other.YesNo),
    String(std::move(other.String)),  // move allocated memory etc. from complex types
    Vector(std::move(other.Vector))
{}

Although, unless your class is itself managing resources, there's no point in writing this at all - the implicit move constructor will do exactly the same thing as the one I wrote.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.