I have the following c++ example (godbolt) that constructs a tuple of MyStruct
in the functions foo
and bar
:
#include <iostream>
#include <tuple>
struct MyStruct {
MyStruct() = default;
MyStruct(const MyStruct&) {
std::cout << "Copy constructor called" << std::endl;
}
MyStruct(MyStruct&&) noexcept {
std::cout << "Move constructor called" << std::endl;
}
~MyStruct() = default;
MyStruct& operator=(const MyStruct&) = default;
MyStruct& operator=(MyStruct&&) noexcept = default;
};
std::tuple<MyStruct, MyStruct> foo() {
return {MyStruct{}, MyStruct{}};
}
std::tuple<MyStruct, MyStruct> bar() {
return {{}, {}};
}
int main() {
std::cout << "Foo" << std::endl;
auto [a, b] = foo();
std::cout << "Bar" << std::endl;
auto [c, d] = bar();
return 0;
}
And produces the following output:
Foo
Move constructor called
Move constructor called
Bar
Copy constructor called
Copy constructor called
When I put this code in c++ insights, it creates the same function for both foo
and bar
. So, my understanding is that both foo and bar should move the object instead of bar copying it. Does anyone know why the behaviour is different?
This question is similar but it's not the same as I'm wondering why bar
copies the value instead of moving it.