On Fri, Jan 13, 2017 at 10:23 AM, Matthew Woehlke
<mwoehlk...@gmail.com> wrote:
>
> ...in particular, it would be nice for this to finally work:
>
> for (auto i : std::add_const(__extend_me make_me_a_list())
`add_const` banned rvalue.
(__extend_me expr1) op expr2
auto &&unnamed = expr1
unnamed op expr2
I think it is worth putting a stake in the ground and *defining* the term "lifetime extension" as the act of converting a temporary's value category to lvalue.
So I'm only referring to lifetime relative to the expression (or block, if we're talking about the explicit lifetime extension case). Meaning, an lvalue, if valid to begin with (on return from f, say) will continue to be valid for the duration of the subsequent evaluation where it is accessible, as far as the compiler inserting destructors is concerned. Or said another way, lvalue lifetimes are naturally scope-delimited. Compared to xvalues, which are disposable from the moment the containing expression is about to consume them, this is an extended lifetime.
I think I'm looking more at the validity of the T& "value" itself (the address where a T lives) than the object therein - granted one could throw in an explicit destructor call in the middle of the expression, but the idea is that when a temporary is created by the compiler, it is reserving space to hold a value, and we are (I think) talking about the lifetime of this reservation. An xvalue temporary's reservation is much shorter than an lvalue temporary's. Could be this correlation of value category to lifetime is about storage, not object, lifetime.
Doesn't a subexpression of type T&, even if that is returned from f(), imply that the value will not be destructed during the evaluation of the rest of the expression it is in?
auto &str = std::string("f00").replace(1, 2, "Something New");
Granted, there is the classic bug of returning a ref to a local from inside f(), but that was destructed before the function even yielded the result. That bug aside, C++ will not (of its own accord) sequence an lvalue destruction during an expression the value appears in, even after it is consumed in a parent expression(that's what xvalues are for).
An xvalue temporary's reservation is much shorter than an lvalue temporary's.