Lifetime extension only occurs when binding directly to references outside of a constructor.
Reference lifetime extension within a constructor would be technically challenging for compilers to implement.
If you want reference lifetime extension, you will be forced to make a copy of it. The usual way is:
struct wrap {
wrap(A&& a) : a(std::move(a))
{}
const char* begin() const { return a.begin(); }
const char* end() const { return a.end(); }
A a;
};
In many contexts, wrap
is itself a template:
template<class A>
struct wrap {
wrap(A&& a) : a(std::forward<A>(a))
{}
const char* begin() const { return a.begin(); }
const char* end() const { return a.end(); }
A a;
};
and if A
is a Foo&
or a Foo const&
, references are stored. If it is a Foo
, then a copy is made.
An example of such a pattern in use would be if wrap
where called backwards
, and it returned iterators that where reverse iterators constructed from A
. Then temporary ranges would be copied into backwards
, while non-temporary objects would be just viewed.
In theory, a language that allowed you to markup parameters to functions and constructors are "dependent sources" whose lifetime should be extended as long as the object/return value would be interesting. This probably is tricky. As an example, imagine new wrap( A{"works"} )
-- the automatic storage temporary now has to last as long as the free store wrap
!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…