Boost logo

Boost :

From: Thomas Wenisch (twenisch_at_[hidden])
Date: 2002-09-04 12:24:57


On Wed, 4 Sep 2002, Anthony Williams wrote:

> David B. Held writes:
> > I just wrote this little utility function, and wondered if it is generally
> > useful.
> >
> > // Requirements:
> > // Ptr must define element_type
> > // Ptr::element_type must be default-constructible
> > template <class Ptr>
> > typename Ptr::element_type const& safe_dereference(Ptr p)
> > {
> > return p ? *p : typename Ptr::element_type();
> > }
> >
> > // Requirements:
> > // T must be default-constructible
> > template <typename T>
> > T const& safe_dereference(T* p)
> > {
> > return p ? *p : T();
> > }
> >
> > In my use case, I am storing shared_ptrs which may or may not actually
> > point to something. I want to be able to dereference it regardless, and
> > just get a default value when the pointer is null (which should be obvious
> > enough from the code).
>
> I can see the point, but this is undefined behaviour --- you are returning a
> reference to a temporary, which as gone out of scope.
>
> Anthony
>

This is incorrect. The code returns a *const* reference to the
temporary. This extends the life of the temporary to the life of the
reference.

The relevant parts of the standard are 12.2 and 8.5.3. Its pretty hard to
piece all the rules together (I think there was a thread on this here or
in comp.lang.c++.moderatord recently), but, basically, 12.2 says that if a
reference is bound to a temporary, the life of the temporary extends to
the life of the reference. 8.5.3 says that only non-volatile const
references may be bound to rvalues (exception: rvalues that can be
converted to lvalues via some conversion sequence). So 12.2 specifies the
lifetime, and 8.5.3 makes the return legal.

Regards,
-Tom Wenisch
Computer Architecture Lab
Carnegie Mellon University


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk