Re: user-defined op= for type with reference member
 
"Paul Bibbings" <paul.bibbings@gmail.com> wrote in message 
news:87aar1dzby.fsf@gmail.com...
"Leigh Johnston" <leigh@i42.co.uk> writes:
"Paul Bibbings" <paul.bibbings@gmail.com> wrote in message
news:87iq5pe056.fsf@gmail.com...
Since I have used the following in another post, can someone just
confirm (or otherwise) whether the following definition of a
user-defined op= for a type with a reference member is well defined?
  class AType
  {
  public:
     AType(int& i)
        : i_(i)
     { }
     // ...
     AType& operator=(const AType& other)
     {
        if (this != &other)
        {
           this->~Atype();
           new (this) AType(other);
        }
        return *this;
     }
  private:
     int& i_;
  };
According to my reading of the example given in [basic.life] ??3.8/7 I
believe that it is, in this instance (since the constructor doesn't
throw, except on bad_alloc).
Regards
Paul Bibbings
Attempting to use this trick to reseat a reference or
destruct/re-construct const members is UB IIRC, there was a thread
about this a few months ago I think.
I had that same recollection, but take a look at ??3.8/7, where the
following example is given:
  struct C {
     int i;
     void f();
     const C& operator=( const C& );
  };
  const C& C::operator=( const C& other)
  {
     if ( this != &other ) {
        this->~??C(); //lifetime of *this ends
        new (this) C(other); // new object of type C created
        f(); //well-defined
     }
     return *this;
  }
  C c1;
  C c2;
  c1 = c2; // well-defined
  c1.f(); //well-defined; c1 refers to a new object of type C
The only relevant difference here is the reference data member, but I
have not been able to find a reason why this should present an especial
problem.  The copy constructor can seat a reference, so I can't see why
using it in the context of a placement new (if that is the right term)
should be problematic.  I will try and find the earlier thread.
Regards
Paul Bibbings
From 3.8/7:
"If, after the lifetime of an object has ended and before the storage which 
the object occupied is reused or
released, a new object is created at the storage location which the original 
object occupied, a pointer that
pointed to the original object, a reference that referred to the original 
object, or the name of the original
object will automatically refer to the new object and, once the lifetime of 
the new object has started, can
be used to manipulate the new object, if:
??? the type of the original object is not const-qualified, and, if a class 
type, does not contain any non-static
data member whose type is const-qualified >>>>>> or a reference type <<<<<<, 
and"
/Leigh