Why RVO is not applied here?
It's not simply performing optimizations. g++ does use RVO here when using -O2
. You should enable optimizations on your compiler to test this out. However, note that even if RVO might be applied by some compilers, it's not mandatory, so you might see different results using different compilers.
Why NOT call the move constructor: B(const B&)?
That is a copy constructor. It's calling the move constructor which is a better match here.
If I remove the B(const B&&), then B(const B&) is called. Weird!
No, it's not weird. The move constructor will not be implicitly defined by the compiler if you define a copy constructor. Therefore, the compiler is picking the copy constructor, since no move constructor is available.
Note that your move constructor should take a non const rvalue reference:
B(B&& b) {
// ...
}
Otherwise, you'd just end up doing the same as in the copy constructor.