Boost logo

Boost :

Subject: Re: [boost] [core] Breaking change to boost::ref in 1.56
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2014-07-14 06:16:26


On Monday 14 July 2014 13:01:40 Peter Dimov wrote:
> Andrey Semashev wrote:
> > Would you expect this code to work:
>
> Unless I'm doing something wrong, this code seems to work with the old
> boost::ref, it also works with the new boost::ref without the collapsing
> overloads. I'm not sure what your point is; are you arguing that the code
> must fail?

Oh, right, I didn't test it, and as I was composing the code I eventually
missed something.

  struct my_class
  {
    void bar();
  };

  struct my_class_const
  {
    void bar() const;
  };

  template< typename T >
  void foo(T const& t)
  {
    typedef typename boost::unwrap_reference<T>::type class_type;
    boost::bind(&class_type::bar, boost::ref(t))();
  }

  template< typename T >
  void foo1(T const& t)
  {
    foo(boost::ref(t));
  }

  foo(my_class_const());
  my_class x;
  foo(boost::ref(x));
  foo1(boost::ref(x));

The point was that (a) unwrap_reference doesn't remove all nested levels of
reference_wrappers, just the top level, so class_type does not have bar when
foo1 is called and (b) boost::bind saves a reference to a reference, so
get_pointer does not work as intended, not to mention that a dangling
reference may be left if the function object call is delayed.


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