1

As per the documentation(), which says:

When an implementation introduces a temporary object of a class that has a non-trivial constructor ([class.default.ctor], [class.copy.ctor]), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor ([class.dtor]). Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) 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.

How to comprehend "Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created."?Could anyboday make it clear by some simple examples?

sunshilong369
  • 646
  • 1
  • 5
  • 17
  • For a less technical paraphrase of the documentation, see [A: Life span of temporary arguments?](https://stackoverflow.com/a/2506800). (It finally occurred to me to search for "full expression" instead of "temporary destroyed".) – JaMiT May 24 '20 at 00:40
  • It's so kind of you.I would read it right now. – sunshilong369 May 24 '20 at 00:49
  • As i have read the documentation aforementioned, one more question raised."`Class CTest; CTest fool(CTest); CTest cTes = func(CTest());`" I think the temporary object(`CTest()` in `fool(CTest())`) should be destoryed after evaluating the entire expression(`CTest cTes = func(CTest());`) and **after evaluating the copy constructor(`CTest cTes=`)**.Am i right?Thank you. – sunshilong369 May 24 '20 at 04:03
  • You've entered one of the places where the terminology gets weird. Technically, `CTest cTes = func(CTest());` is not an "expression", but it is a "full-expression", as crazy as that sounds. So, yes, the temporary is destroyed after the copy construction. – JaMiT May 24 '20 at 21:59
  • @JaMiT Amazing!What are the differences between "expresssion" and "full-expression"? – sunshilong369 May 25 '20 at 01:24
  • That looks like a new question to me. – JaMiT May 25 '20 at 01:39

2 Answers2

4

Simple example. This expression produces a temporary object:

std::string("test")

Here, that expression is used as a subexpression:

function(std::string("test"));
// point A

At point A, the temporary object has been destroyed because the point is after the full-expression where the temporary object was created.


Here is an example of how to write a bug if this rule is not understood:

const std::string& function(const std::string& arg) {
    return arg;
}

const std::string& ref = function("test");
std::cout << ref;

Here, the temporary object that was created as the argument is destroyed after the full expression, and therefore ref has become invalid - a dangling reference. The behaviour is undefined when the invalid reference is inserted into the output stream.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thank you for your clarification.You mean the the temporary object(`std::string("test")`) is destroyed **after the return** of `function`?Could i think in this way. – sunshilong369 May 24 '20 at 00:15
  • @sunshilong369 Yes. The temporary object is alive through the entire function, but not alive as soon as the function has returned. – eerorika May 24 '20 at 00:23
1

An explanation that works in many cases is that temporary objects are destroyed when execution reaches the semicolon at the end of the statement. Some language constructs (such as a for loop) are not covered by this explanation, so don't push it too hard. For a better explanation of the exceptions, see Statement that isn't a full-expression.

As one example:

i = foo1(foo2(std::string("test")));

The temporary string is kept alive until after the assignment, as the assignment occurs before the end of the statement. (In this case, the full expression is the statement.)

JaMiT
  • 14,422
  • 4
  • 15
  • 31
  • Thank for your clarification.Asume that this is an expression that `foo1(foo2((std::string("test"))));`, do you mean the temporary object(`std::string("test")`) should be destroyed **after** the return of the function `foo1`? – sunshilong369 May 24 '20 at 00:22
  • @sunshilong369 Yes. – JaMiT May 24 '20 at 00:26