Defaulted destructor inhibits move

Today I learned: Explicitly defaulting a class’s destructor causes the compiler not to implicitly define any move constructor at all. Thus:

struct Oops {
    std::shared_ptr<int> p;
    ~Oops() = default;
};
static_assert(std::is_copy_constructible_v<Oops>);
static_assert(std::is_move_constructible_v<Oops>);

Struct Oops is “move-constructible” in the sense that

Oops b = std::move(a);

will compile. But what it actually does is make a copy!

Posted 2018-07-07