1

I'm trying to make a move operator for a class (which we will call A) that contains another reference to another class (which we will call B), whose copy constructor has been implicitly deleted because it contains another reference. A simple example has been shown below.

class B
{
   public:
    int & num;

    B(int & _num) : num(_num) {}
};

class A
{
   public:
    B & b;

    A(B & _b) : b(_b) {}
    A & operator=(A && other)
    {
        b = other.b; //< Error
        return *this;
    }
};

When I try to compile, I get this error:

error: object of type 'B' cannot be assigned because its copy assignment operator is implicitly deleted b = other.b;

A couple of questions:

1) Why is the implicit copy assignment operator deleted in B? Or even A for that matter?

2) Why does it matter if B has a copy constructor or operator if I'm trying to copy the reference, not the object? Am I not doing that part right?

iHowell
  • 2,263
  • 1
  • 25
  • 49
  • "Why" questions usually are answered as "Because the standard says so". Delving into the actual reasons the committee decided that is usually a tricky matter filled with anecdote and opinion. – AndyG Jun 21 '19 at 20:04
  • @AndyG disagree. Asking for rationale is a good thing, Standard wasn't given us by mysterious creatures, it was decided through very serious deliberations and it is a living organism. Sometimes asking about rationale leads to standard being changed, since rationale hasn't been found solid. – SergeyA Jun 21 '19 at 20:13
  • @SergeyA: What I'm trying to say is that a definitive StackOverflow answer to "Why is the language this way" would have some kind of citation of a decision made by the committee (or the answerer is a primary source themselves). A lot of reasons are common knowledge (certainly not all of them), and we can often come up with our own pros and cons of a language feature being one way or another, and those are definitely useful, too, but IMO don't constitute a "definitive" answer. – AndyG Jun 21 '19 at 20:17
  • I have seen some such questions with answers including quotes from proposal documents or meeting notes explaining the choices made. Admittedly, that's not always possible. – aschepler Jun 21 '19 at 20:18

1 Answers1

3

2) Why does it matter if B has a copy constructor or operator if I'm trying to copy the reference, not the object? Am I not doing that part right?

Copy assignment of a reference assigns the referred object. It is not possible to re-seat a reference i.e. it is not possible to make reference refer another object.

1) Why is the implicit copy assignment operator deleted in B? Or even A for that matter?

Because they both have a reference member.

Why are copy operators implicitly deleted in classes with reference fields?

Because the assignment of the referred object, is counter-intuitive default behaviour for an assignment operator of a class, and therefore such assignment operator is not generated implicitly.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • I might say, reference as class members are weird beasts. I am not even sure they are good use case. – SergeyA Jun 21 '19 at 20:14
  • Is it probably better to just use `reference_wrapper`s then? I know they are copyable and movable. – iHowell Jun 21 '19 at 21:03
  • @iHowell if you need a re-seatable reference, then you can use `std::reference_wrapper` indeed. – eerorika Jun 21 '19 at 21:12