Here's a code from Stroustrup's "The C++ Programming Language" that implements a finally
which I cannot quiet understand where the destructor gets called.
template<typename F> struct Final_action
{
Final_action(F f): clean{f} {}
~Final_action() { clean(); }
F clean;
}
template<class F>
Final_action<F> finally(F f)
{
return Final_action<F>(f);
}
void test(){
int* p=new int{7};
auto act1 = finally( [&]{delete p;cout<<"Goodbye,cruel world\n";} );
}
I have two questions around this:
According to the author, the
delete p
only gets called once: when act1 goes out of scope. But from my understanding: first,act1
will be initialized with the copy constructor, then the temporary objectFinal_action<F>(f)
in the functionfinally
gets destructed, callingdelete p
for the first time, then a second time at the end of the functiontest
whenact1
is out of scope. Where am I getting it wrong?Why is the
finally
function needed? Can't I just defineFinal_action act1([&]{delete p;cout<<"Goodbye,cruel world\n"})
? Is that the same?
Also, if anyone can think of a better title, please modify the current one.
UPDATE: After some further thinking, I'm now convinced that the destructor may be called thrice. The additional one is for the temporary objected auto-generated in the calling function void test()
used as the argument to the copy constructor of act1
. This can be verified with -fno-elide-constructors
option in g++. For those who have the same question as me, see Copy elision as well as Return value optimization as pointed out in the answer by Bill Lynch.
auto
thought this was easier to read. – ItaFinal_action<???>
because of the lambda. – Harpistoperator=
are both set to delete to preventFinal_action
from being copied. Furthermore your example code misses at least one semicolon after thecout
– Miraoperator ()
. – Harpiststd::function
. – Harpist