#include <iostream>
class Int {
public:
explicit Int(int integer) : i(integer) {
std::cout << "\tInt constructor\n";
}
Int(const Int& other) {
std::cout << "\tInt copy constructor\n";
i = other.i;
}
Int& operator=(const Int& other) {
std::cout << "\tInt copy assignment operator\n";
i = other.i;
return *this;
}
Int(const Int&& other) {
std::cout << "\tInt move constuctor\n";
i = other.i;
}
Int& operator=(const Int&& other) {
std::cout << "\tInt move assignment operator\n";
i = other.i;
return *this;
}
~Int() = default;
private:
int i;
};
struct B {
public:
explicit B(Int integer) : i(std::move(integer)) {}
private:
Int i;
};
int main() {
std::cout << "create B from rvalue\n";
B b_from_rvalue(Int(6));
return 0;
}
I expected the Int to be moved to the constructor, then to be moved again when doing std::move.
If I do instead:
B b_from_rvalue(std::move(Int(6)));
Then it does call the move constructor twice.
So it looks to me a lot like return value optimization, but I'm not sure.
The behaviour is the same on gcc and clang with any optimization flag.