|
524 | 524 |
|
525 | 525 | \pnum
|
526 | 526 | The third context is when a reference is bound to a
|
527 |
| -temporary.\footnote{The same rules apply to initialization of an |
| 527 | +temporary object.\footnote{The same rules apply to initialization of an |
528 | 528 | \tcode{initializer_list} object~(\ref{dcl.init.list}) with its
|
529 | 529 | underlying temporary array.}
|
530 |
| -The temporary to which the reference is bound or the temporary |
| 530 | +The temporary object to which the reference is bound or the temporary object |
531 | 531 | that is the complete object of a subobject to which the reference is bound
|
532 |
| -persists for the lifetime of the reference except: |
| 532 | +persists for the lifetime of the reference if the glvalue |
| 533 | +to which the reference is bound |
| 534 | +was obtained through one of the following: |
| 535 | +\begin{itemize} |
| 536 | +\item |
| 537 | + a temporary materialization conversion~(\ref{conv.rval}), |
| 538 | +\item |
| 539 | + \tcode{(} \grammarterm{expression} \tcode{)}, |
| 540 | + where \grammarterm{expression} is one of these expressions, |
| 541 | +\item |
| 542 | + subscripting~(\ref{expr.sub}) of an array operand, |
| 543 | + where that operand is one of these expressions, |
| 544 | +\item |
| 545 | + a class member access~(\ref{expr.ref}) using the \tcode{.} operator |
| 546 | + where the left operand is one of these expressions and |
| 547 | + the right operand designates a non-static data member of non-reference type, |
| 548 | +\item |
| 549 | + a pointer-to-member operation~(\ref{expr.mptr.oper}) using the \tcode{.*} operator |
| 550 | + where the left operand is one of these expressions and |
| 551 | + the right operand is a pointer to data member of non-reference type, |
| 552 | +\item |
| 553 | + a \tcode{const_cast}~(\ref{expr.const.cast}), |
| 554 | + \tcode{static_cast}~(\ref{expr.static.cast}), |
| 555 | + \tcode{dynamic_cast}~(\ref{expr.dynamic.cast}), or |
| 556 | + \tcode{reinterpret_cast}~(\ref{expr.reinterpret.cast}) |
| 557 | + converting, without a user-defined conversion, |
| 558 | + a glvalue operand that is one of these expressions |
| 559 | + to a glvalue that refers |
| 560 | + to the object designated by the operand, or |
| 561 | + to its complete object or a subobject thereof, |
| 562 | +\item |
| 563 | + a conditional expression~(\ref{expr.cond}) that is a glvalue |
| 564 | + where the second or third operand is one of these expressions, or |
| 565 | +\item |
| 566 | + a comma expression~(\ref{expr.comma}) that is a glvalue |
| 567 | + where the right operand is one of these expressions. |
| 568 | +\end{itemize} |
| 569 | +\begin{example} |
| 570 | +\begin{codeblock} |
| 571 | +template<typename T> using id = T; |
| 572 | + |
| 573 | +int&& a = id<int[3]>{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} |
| 574 | +const int& b = static_cast<const int&>(0); // temporary \tcode{int} has same lifetime as \tcode{b} |
| 575 | +int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0); |
| 576 | + // exactly one of the two temporaries is lifetime-extended |
| 577 | +\end{codeblock} |
| 578 | +\end{example} |
| 579 | +\begin{note} |
| 580 | +An explicit type conversion~(\ref{expr.type.conv}, \ref{expr.cast}) |
| 581 | +is interpreted as |
| 582 | +a sequence of elementary casts, |
| 583 | +covered above. |
| 584 | +\begin{example} |
| 585 | +\begin{codeblock} |
| 586 | +const int& x = (const int&)1; // temporary for value 1 has same lifetime as x |
| 587 | +\end{codeblock} |
| 588 | +\end{example} |
| 589 | +\end{note} |
| 590 | +\begin{note} |
| 591 | +If a temporary object has a reference member initialized by another temporary object, |
| 592 | +lifetime extension applies recursively to such a member's initializer. |
| 593 | +\begin{example} |
| 594 | +\begin{codeblock} |
| 595 | +struct S { |
| 596 | + const int& m; |
| 597 | +}; |
| 598 | +const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} |
| 599 | +\end{codeblock} |
| 600 | +\end{example} |
| 601 | +\end{note} |
533 | 602 |
|
| 603 | +The exceptions to this lifetime rule are: |
534 | 604 | \begin{itemize}
|
535 | 605 | \item A temporary object bound to a reference parameter in a function call~(\ref{expr.call})
|
536 | 606 | persists until the completion of the full-expression containing the call.
|
|
541 | 611 | \begin{codeblock}
|
542 | 612 | struct S { int mi; const std::pair<int,int>& mp; };
|
543 | 613 | S a { 1, {2,3} };
|
544 |
| -S* p = new S{ 1, {2,3} }; // Creates dangling reference |
| 614 | +S* p = new S{ 1, {2,3} }; // creates dangling reference |
545 | 615 | \end{codeblock}
|
546 | 616 | \end{example} \begin{note} This may introduce a dangling reference, and implementations should issue a warning in such a case. \end{note}
|
547 | 617 | \end{itemize}
|
|
0 commit comments