Description
Full name of submitter (unless configured in github; will be published with the issue): Jakub Jelinek
Reference (section label): [class.temporary]
Link to reflector thread (if any):
Issue description: P1306R5 adjusted the fourth context bullet so that it applies also to enumerating expansion statements.
The rest of the bullet talks about for-range-initializer which doesn't apply to enumerating expansion statement and references, but in enumerating expansion statements there might be no references.
"The fourth context is when a temporary object is created in the for-range-initializer of either a range-based for statement or an enumerating expansion statement ([stmt.expand]). If such a temporary object would otherwise be destroyed at the end of the for-range-initializer full-expression, the object persists for the lifetime of the reference initialized by the for-range-initializer."
So, I think enumerating expansion statement temporary extension should probably be handled in a separate bullet and make it clear what is being extended and in which cases.
Consider
struct T { int t; };
struct S { const T &s; }; S foo (const T &x) { S s {x}; return s; }
void bar () {
template for (auto a = { 42, foo ({ 42 }), 1LL })
;
}
For S1 this adds auto a = foo ({ 42 }); declaration before instantiation of the compound-statement. a is not a reference, in this case it contains a reference non-static data member, but it could very well be e.g. a pointer as well. Is the intent that the temporary is only destroyed at the end of the compound-statement, regardless if for-range-declaration has reference type or not?
Suggested resolution: