rustyx
rustyx

Reputation: 85412

Default move constructor behavior with std::string attributes

I have a simple data class in which I want to save some typing and let the compiler generate the move constructor and assignment operator:

class A
{
public:
  A(int x, std::string&& y) : x_(x), y_(std::move(y)) {}
  A(A && a) = default;
  A& operator= (A && a) = default;
private:
  int x_;
  std::string y_;
};

Assuming my compiler is 100% C++11 compliant, will it do the right thing with the std::string y_ attribute? Will it apply move semantics to it?

Upvotes: 3

Views: 1146

Answers (2)

Barry
Barry

Reputation: 303287

The rule, from [class.copy], is:

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members.

So in this case, it will move-construct/assign both x_ and y_. from the A that you're move-construct/assigning from.


Note that a defaulted move constructor can still perform copies if one of its members has the move constructor not implicitly defined:

struct A {
    A() { }
    A(A const& ) { }
    // A(A&& ) not implicitly defined because of the copy ctor
};

struct B {
    B() = default;
    B(B&& ) = default;
    B& operator=(B&& ) = default;

    A a;
};

B b;
B c = std::move(b); // copy-constructs c.a from b.a

Upvotes: 3

Quentin
Quentin

Reputation: 63144

Yes, it will, that's the whole point of generating special member functions.

However, you forgot to move the parameter of the constructor into the member:

A(int x, std::string&& y) : x_(x), y_(std::move(y)) {}
//                                    ^^^^^^^^^^ ^

Upvotes: 1

Related Questions