Whose destructor is this?

In the below code:

#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 out the output with my reasoning):

 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 that outputs 42? I cannot understand this.

+3


source to share


1 answer


Automatic variables are destroyed in the reverse order of declaration, so the specified destructor is a destructor s1

.

The reason it takes a value {"", 42}

at this point in the program is because the return value is f

initialized with a move construct; that is, it is s1

considered the value of x. This follows from the rule in [class.copy] / 32:



When the criteria for performing a copy operation are met, or are met, except that the source of object is a function parameter and the object to be copied is specified by an lvalue, by overloading select, the constructor for the copy is first executed as if the object were denoted by an rvalue.

+2


source







All Articles