Reputation: 6958
In the code below:
#include <string>
#include <iostream>
struct S {
std::string a;
int b;
S(const S&) = default;
S(S&&) = default;
S& operator=(const S&) = default;
S& operator=(S&&) = default; // not required here but should be added for completeness
~S() {
std::cout << a << " " << b << std::endl;
}
};
S f(S arg) {
S s0{};
S s1(s0); //s1 {s0}; in the book
s1 = arg;
return s1;
}
int main()
{
S s3{"tool",42};
f(s3);
}
I get the following output (I commented the output with my reasonings):
42 //???
0 // s0 is destroyed
tool 42 // arg is destroyed
tool 42 // return value of f() is destroyed
tool 42 // s3 is destroyed
whose destructor is the one which outputs 42?? I can't understand it
Upvotes: 3
Views: 100
Reputation: 157444
Automatic variables are destroyed in reverse order of declaration, so the destructor indicated is the destructor of s1
.
The reason it takes the value {"", 42}
at that point in the program is that the return value of f
is being initialized by move construction; that is, s1
is being treated as an xvalue. This follows from the rule in [class.copy]/32:
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
Upvotes: 2