2015-08-12 7:29 GMT+08:00 Gavin Lambert <gavinl@compacsort.com>:
On 11/08/2015 21:39, Stephan Bergmann wrote:
On 08/11/2015 10:27 AM, TONGARI J wrote:
template<class T>
struct wrapper
{
     wrapper() = default;

     wrapper(boost::intrusive_ptr<T> const& p) : _p(p) {}

     boost::intrusive_ptr<T> const& get_ptr() const
     {
#if 0
         // This is OK.
         if (_p)
             return _p;
         return nullptr;
#else
         // Strange behavior.
         return _p ? _p : nullptr;
#endif
     }

In both cases, you return a reference to a temporary, incurring
undefined behavior.

_p is a field, so it's not a temporary as long as its instance isn't. get_ptr() is invoked on named instances that live longer than the test() function, so they're not temporaries either.

While granted it's probably not a good idea to create a tuple from references, I don't actually see any undefined behaviour in this particular example.  What am I missing?

The nullptr -> boost::intrusive_ptr<T> makes it a temporary.