“Temporary objects” vs “temporary expressions”
15.2 [class.temporary]
Johannes Schaub

Created on 2011-04-16.00:00:00 last changed 29 months ago


Date: 2017-07-15.00:00:00

[Voted into the WP at the July, 2017 meeting as document P0727R0.]

Date: 2017-03-15.00:00:00

Proposed resolution (March, 2017):

  1. Change 8 [expr] paragraph 12 as follows:

  2. ...is applied. [Note: If the expression is an lvalue of class type, it must have a volatile copy constructor to initialize the temporary object that is the result object of the lvalue-to-rvalue conversion. —end note] The glvalue expression...
  3. Change 15.2 [class.temporary] paragraph 6 as follows:

  4. The third context is when a reference is bound to a temporary object.116 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 referring to the temporary object was obtained through one of the following:

    • a temporary materialization conversion (7.4 [conv.rval]),

    • ( expression ), where expression is one of these expressions,

    • subscripting (8.2.1 [expr.sub]) of an array operand, where that operand is one of these expressions,

    • a class member access (8.2.5 [expr.ref]) using the . operator where the left operand is one of these expressions and the right operand designates a non-static data member of non-reference type,

    • a pointer-to-member operation (8.5 [expr.mptr.oper]) using the .* operator where the left operand is one of these expressions and the right operand is a pointer to data member of non-reference type,

    • a const_cast (8.2.11 [expr.const.cast], static_cast (8.2.9 [expr.static.cast]), dynamic_cast (8.2.7 [expr.dynamic.cast]), or reinterpret_cast (8.2.10 [expr.reinterpret.cast]) converting a glvalue operand that is one of these expressions to a glvalue referring to that operand,

    • a conditional expression (8.16 [expr.cond]) that is a glvalue where the second or third operand is one of these expressions, or

    • a comma expression (8.19 [expr.comma]) that is a glvalue where the right operand is one of these expressions.


      template<typename T> using id = T;
      int&& a = id<int[3]>{1, 2, 3}[i];          // temporary array has same lifetime as a
      const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b
      int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
                                                 // exactly one of the two temporaries is lifetime-extended

    end example] [Note: If a temporary object has a reference member initialized by another temporary object, lifetime extension applies recursively to such a member's initializer. [Example:

      struct S {
        const int& m;
      const S& s = S{1};  // both S and int temporaries have lifetime of s

    end example] —end note]

    except The exceptions to this lifetime rule are:

    • A temporary object bound to a reference parameter...

  5. Change [over.match.copy] bullet 1.2 as follows:

    • When the type of the initializer expression is a class type “cv S”, the non-explicit conversion functions of S and its base classes are considered. When initializing a temporary object (12.2 [class.mem]) to be bound to the first parameter of a constructor...

  6. Change [res.on.arguments] bullet 1.3 as follows:

    • ...[Note: If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument std::move(x)), the program is effectively asking that function to treat that lvalue as a temporary object. The implementation is free...

  7. Change [util.smartptr.weak.assign] paragraph 2 as follows:

  8. Remarks: The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary object.
  9. Change the footnote in [template.valarray.overview] paragraph 1 as follows:

  10. ...generalized subscript operators. [Footnote: The intent is to specify an array template that hass the minimum functionality necessary to address aliasing ambiguities and the proliferation of temporaries temporary objects. Thus... —end footnote]
  11. Change the last bullet of C.2.16 [diff.cpp03.input.output] as follows:

    • initializing a const bool & which would bind to a temporary object.

This resolution also resolves issues 943 and 1076.

Date: 2014-11-24.00:00:00

Additional note, November, 2014:

Concerns have been raised that the meaning of “corresponding temporary object” is not clear enough in the proposed wording. In addition, N3918 says that it resolves issue 1300, but that issue is 1) marked as a duplicate of issue 914 and 2) the subject of continuing deliberations in EWG. This issue is being returned to "review" status to allow CWG to address these concerns.

Date: 2014-02-15.00:00:00

Proposed resolution (February, 2014) [SUPERSEDED]:

The resolution is contained in document N3918.

This resolution also resolves issues 1651 and 1893.

Date: 2013-01-14.00:00:00

The Standard is insufficiently precise in dealing with temporaries. It is not always clear when the term “temporary” is referring to an expression whose result is a prvalue and when it is referring to a temporary object.

(See also issue 1568.)

Date User Action Args
2018-02-27 00:00:00adminsetmessages: + msg6142
2018-02-27 00:00:00adminsetmessages: + msg6141
2018-02-27 00:00:00adminsetstatus: drafting -> drwp
2014-11-24 00:00:00adminsetmessages: + msg5209
2014-11-24 00:00:00adminsetstatus: ready -> drafting
2014-03-03 00:00:00adminsetmessages: + msg4837
2014-03-03 00:00:00adminsetstatus: drafting -> ready
2013-10-14 00:00:00adminsetstatus: open -> drafting
2011-04-16 00:00:00admincreate