In his "C++ Move Semantics" book Nicolai M. Josuttis states that moving an object that contains a non-movable member amongst movable members with the generated move constructor move all members but the non-movable one (which is copied). Below is code snippet which is a variation of the example in the book.
#include <iostream>
class Copyable {
std::string name;
public:
explicit Copyable(std::string name): name(std::move(name)) {}
// Copying enabled
Copyable(const Copyable& other): name(other.name) {
std::cout << "Copyable copy ctor" << std::endl;
}
Copyable& operator=(const Copyable& other) {
name=other.name;
std::cout << "Copyable op=" << std::endl;
return *this;
}
// Moving disabled with no copy fallback
Copyable(Copyable&&) = delete;
Copyable& operator=(Copyable&&) = delete;
};
class Movable {
std::string name;
public:
explicit Movable(std::string name): name(std::move(name)) {}
// Copying enabled
Movable(const Movable& other): name(other.name) {
std::cout << "Movable copy ctor" << std::endl;
}
Movable& operator=(const Movable& other) {
name=other.name;
std::cout << "Movable op=" << std::endl;
return *this;
}
// Moving enabled
Movable(Movable&& other) noexcept: name(std::move(other.name)) {
std::cout << "Movable move ctor" << std::endl;
}
Movable& operator=(Movable&& other) noexcept {
name = std::move(other.name);
std::cout << "Movable move op=" << std::endl;
return *this;
}
};
class Container {
Copyable copyable;
Movable movable;
public:
Container(Copyable copyable, Movable movable): copyable(copyable), movable(std::move(movable)) {}
// Both copying and moving enabled by default
};
int main() {
Copyable c{"copyable"};
Movable m{"movable"};
Container container{c, m};
Container container2{std::move(container)};
}
Compiled with GCC on x86-64 with C++17 standard following output is produced:
Container created and initialized:
Copyable copy ctor
Movable copy ctor
Copyable copy ctor
Movable move ctor
Container moved:
Copyable copy ctor
Movable copy ctor
No move ctor is called for the movable member once the container is moved. According to the book move ctor should be called for the Movable member, shouldn't it?