0
class B
{
public:
    B(int& a) :ref(a){}
    B(B const&) = default;
    int& ref;
};


void main()
{
    int a1 = 1, a2 = 2;
    B b1(a1), b2(b1), b3(a2);
    b3 = b1;

}

If the implicitly-defined copy assignment operator of compiler's implementation is,

B& operator=(const B& rhs)
{
    this->ref = rhs.ref;
    return *this;
}

why cannot be generated for references? The initial alias bounding to variable a is not affected, because in the copy assignment operator the numeric value of reference variable ref is altered.

maclaud
  • 182
  • 10

1 Answers1

1

It can do it because reference can't be rebound to another one.

If the compiler would generate a function like you provided, I would do this:

struct Ref {
    int& num;
    // hypotetical operator= generated
};

// ...

int a = 2;
int b = 5;

Ref ra{a};
Ref rb{b};

ra = rb; // now a = 5. Quite confusing.

a = 3; // still changes what value `ra.num` yeild. rb is not affected.

// will print "false".
std::cout << std::boolalpha << (ra.num == rb.num) << std::endl;

That would lead to some nasty errors.

My preferred solution to this problem is to not care. I think that the operator= is not absolutly required for most use cases.

However, if you really want to provide an operator= to the users of your class, you can hold a pointer or a std::reference_wrapper instead of a reference. Both will allow your class to be assignable, making your reference rebindable. Between those two, I usually prefer pointers as they are more straightforward to use in my opinion.

struct Ref {
    std::reference_wrapper<int> num;
};

// -- or --

struct Ref {
    Ref(int& ref) : num{&ref} {}

    int* num;
};

// ...

int a = 2;
int b = 5;

Ref ra{a};
Ref rb{b};

ra = rb; // now ra.num and rb.num are bound to the same reference.
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141