So I read this post:
How is "=default" different from "{}" for default constructor and destructor?
Which discusses why:
~Widget() = default;
Isn't the same as:
~Widget() {}
However, it's also true that the "=default" case is different than the implicitly declared case. In some sense, =default doesn't actually give you the default, which is kinda odd.
Consider the following program:
class A
{
public:
    A(std::string str)
    {
        m_str = str;
    } 
    ~A() = default;
    A(A const& rhs)
    {
        printf("Got copied\n");
        m_str = rhs.m_str;
    }
    A(A&& rhs)
    {
        printf("Got moved\n");
        m_str = std::move(rhs.m_str);
    }
    std::string m_str;
};
class B 
{
public:
    B(std::string test) : m_a(test)
    {
    }
    ~B() = default;
    A m_a;
};
int main()
{
    B b("hello world");
    B b2(std::move(b));
    return 0;
}
Running this program will print "Got copied", unless you comment out the defaulted ~B() in which case it will print "Got moved". So why is this? I think "=default" is pretty confusing considering both this and the implicitly declared destructor are supposed to produce "trivial destructors".
 
    