Dean
Dean

Reputation: 6958

Whose destructor is this one?

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

Answers (1)

ecatmur
ecatmur

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

Related Questions