Reputation: 33395
This outputs F~
but I was expecting ~F
#include <iostream>
struct Foo {
int _x;
operator const int & () const {return _x;}
~ Foo () {std :: cout << "~";}
};
void foo (const int &)
{
std :: cout << "F";
}
int main ()
{
foo (Foo ());
}
I constructed this as a counterexample to show that the most-important-const is an exception rather than a rule. It is normally written as
when a const reference binds to a temporary, then the lifetime of that temporary is extended to the lifetime of the reference
I was trying to illustrate that, although Foo()
is a temporary, the reference to _x
returned by the conversion operator is not, and that the above code is unsafe.
But the output seems to prove that the example is safe, the lifetime of the temporary Foo()
is extended by the existence of a const reference to one of its members.
Is this right? Where in the standard is this specified?
Upvotes: 7
Views: 292
Reputation: 67723
But your Foo
instance here was always going to live until the semicolon ending the statement in which it was created. Passing a reference to a member into a function call didn't change that.
Try:
int const &ref = Foo();
foo(ref);
versus
Foo const &ref = Foo(); // or function returning temp
foo(ref);
Upvotes: 0
Reputation: 299790
The general rule, regarding temporaries, is that their life ends when the full expression they are part of ends (informally, when reaching the ;
).
12.2 Temporary objects
3/ [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.
Upvotes: 6
Reputation: 476990
There's no magic here. All function arguments live in the scope of the caller, including temporaries. The temporary Foo()
is constructed in the scope of the caller, and destroyed at the end of the line.
So whatever the function foo()
does happens before its arguments in main()
are destroyed.
Upvotes: 1
Reputation: 170489
That's because the temporary survives for the whole duration of function call. When you do foo (Foo ());
here's what happens:
Foo
is contructed, thenoperator const int&
is called on the temporaryfoo()
is called and this outputs F
foo()
returns temporary Foo
is destroyed and this outputs ~
Upvotes: 1