When an object of class type X
is passed to or returned from a function,
if each copy constructor, move constructor, and destructor of X
is either trivial or deleted,
and X
has at least one non-deleted copy or move constructor,
implementations are permitted
to create a temporary object
to hold the function parameter or result object.

The temporary object is constructed
from the function argument or return value, respectively,
and the function's parameter or return object
is initialized as if by
using the non-deleted trivial constructor to copy the temporary
(even if that constructor is inaccessible
or would not be selected by overload resolution
to perform a copy or move of the object).

When an implementation introduces a temporary object of a class that has a
non-trivial constructor ([class.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.

In either case, if the constructor has one or more default arguments,
the destruction of every temporary created in a default argument is
sequenced before the construction of the next array element, if any.

The third context is when a reference is bound to a
temporary object.39

The temporary object to which the reference is bound or the temporary object
that is the complete object of a subobject to which the reference is bound
persists for the lifetime of the reference if the glvalue
to which the reference is bound
was obtained through one of the following:

converting, without a user-defined conversion,
a glvalue operand that is one of these expressions
to a glvalue that refers
to the object designated by the operand, or
to its complete object or a subobject thereof,

The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

The destruction of a temporary whose lifetime is not extended by being
bound to a reference is sequenced before the destruction of every
temporary which is constructed earlier in the same full-expression.

If the lifetime of two or more temporaries to which references are bound ends
at the same point,
these temporaries are destroyed at that point in the reverse order of the
completion of their construction.

In addition, the destruction of temporaries bound to references shall
take into account the ordering of destruction of objects with static, thread, or
automatic storage duration ([basic.stc.static], [basic.stc.thread], [basic.stc.auto]);
that is, if
obj1
is an object with the same storage duration as the temporary and
created before the temporary is created
the temporary shall be destroyed before
obj1
is destroyed;
if
obj2
is an object with the same storage duration as the temporary and
created after the temporary is created
the temporary shall be destroyed after
obj2
is destroyed.

The expression
S(16) + S(23)
creates three temporaries:
a first temporary
T1
to hold the result of the expression
S(16),
a second temporary
T2
to hold the result of the expression
S(23),
and a third temporary
T3
to hold the result of the addition of these two expressions.