P0727R0
Jens Maurer <jens.maurer@gmx.net>
2017-07-10

P0727R0: Core Issue 1299: Temporary objects vs temporary expressions

This paper presents the proposed wording to resolve core issue 1299. The drafting below also addresses core issues 943 and 1076.

Proposed wording

Change in 8 expr paragraph 12:
... [ 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 ] ...
Change in 15.2 class.temporary paragraph 6:
The third context is when a reference is bound to a temporary object. [ Footnote: The same rules apply to initialization of an initializer_list object (8.6.4) with its underlying temporary array. ] 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: [ Example:
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
] [ Note: An explicit type conversion (8.2.3 [expr.type.conv] and 8.4 [expr.cast]) is interpreted as a sequence of elementary casts, covered above. [ Example:
  const int& x = (const int&)1;   // temporary for value 1 has same lifetime as x
-- end example ] -- end note ] [ 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:

Change in 16.3.1.4 over.match.copy paragraph 1:
Change in 20.5.4.9 res.on.arguments paragraph 1:
Change in 23.11.2.3.3 util.smartptr.weak.assign paragraph 2:
Remarks: The implementation may meet the effects (and the implied guarantees) via different means, without creating a temporary object.
Change in 29.7.2.1 template.valarray.overview paragraph 1:
... The illusion of higher dimensionality may be produced by the familiar idiom of computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators. [ Footnote: The intent is to specify an array template that has the minimum functionality necessary to address aliasing ambiguities and the proliferation of temporaries temporary objects. Thus, the valarray template is neither a matrix class nor a field class. However, it is a very useful building block for designing such classes. ]
Change in C.2.16 diff.cpp03.input.output:
[ ... ] a const_cast, static_cast, dynamic_cast, or reinterpret_cast 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, [ ... ] For (c) above, I suggest: [ ... ] if the glvalue to which the reference is bound was obtained through one of the following: [ ... ]