1

I have a problem where.. Well, I'm not sure. I really don't know what it means. I have used this same paradigm illustrated below, where I create an object within a class and give that object a reference to the class. This design is used as an event handler.

I added a very unrelated piece of code where I loop through a map of objects and re-assign them. It has brought up an issue due to the use of the = operator. But I still don't actually know what it's complaining about.

// Example program
#include <iostream>
#include <string>
#include <map>

class A {  
    public:
        class Handler {
            public:
                Handler(A &a):a(a){}
                virtual void HandleIt(){
                    a.DoThings();   
                }
                A &a;
        };
    
        A():my_handler(*this){}
        Handler my_handler;
        void DoThings(){
            std::cout << "Im doing things";   
        }
};

std::map<std::string, A> my_map;

void ReplaceInMap(A &a){
    std::map<std::string, A>::iterator it;
    for(it = my_map.begin(); it != my_map.end(); ++it){
        it->second = a;
    }
}

int main()
{
    A a;
    A b;
    A c;
    
    my_map.insert(std::make_pair<std::string, A>("A!", a));
    my_map.insert(std::make_pair<std::string, A>("B!", b));
    my_map.insert(std::make_pair<std::string, A>("C!", c));
    
    ReplaceInMap(a);
}

C++ 98

In member function 'A::Handler& A::Handler::operator=(const A::Handler&)':
8:15: error: non-static reference member 'A&A::Handler::a', can't use default assignment operator  
In member function 'A& A::operator=(const A&)': 6:7: 
note: synthesized method 'A::Handler& A::Handler::operator=(const A::Handler&)' first required here   
In function 'void ReplaceInMap(A&)': 29:20: note: synthesized method 'A& A::operator=(const A&)' first required here

http://cpp.sh/4chmu

What does this error mean? What is the problem?

  • Does this answer your question? ['non-static reference member, can't use default assignment operator'](https://stackoverflow.com/questions/22437903/non-static-reference-member-cant-use-default-assignment-operator) – kesarling He-Him Aug 12 '20 at 03:12
  • 1
    The problem is exactly what is in the error - you are trying to copy your class, but the implicit copy assignment operator is deleted because Handler also has a deleted copy assignment, and *that* happens because it has an `A&` as a member. You will have to define your own copy ctor and assigment for both classes. – shananton Aug 12 '20 at 03:15
  • 1
    @d4rk4ng31 I don't see what's wrong with `a(a)` there... Seems like that is doing exactly what is expected - initializing the member reference :thinking: Edit: I see now that you're talking about a copy ctor, but there's no copy ctor defined in the code, so, not sure what you mean by that – shananton Aug 12 '20 at 03:16
  • @d4rk4ng31 The first "a" is the member and the second is the parameter. That is, there is no shadowing. (It's not a copy constructor, though.) – molbdnilo Aug 12 '20 at 03:24
  • @molbdnilo Well, there is shadowing in the case of the initialiser. There's just no shadowing in the *mem-initializer-id*. – eerorika Aug 12 '20 at 03:28

1 Answers1

2

What does this error mean?

It means what it says literally. The assignment operator of A and consequently Handler cannot be used.

Important points:

  • References are not assignable.
  • The class contains a reference member, and no user defined assignment operator. Therefore the class is not assignable.
  • You attempt to assign objects of that class.

What is the problem?

You attempt to assign a non-assignable class.

Your options are:

  • Don't use a reference member. Use a pointer or a reference wrapper (standard library has one since C++11) both of which are assignable.
  • Don't assign the object.
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • I can't really believe it's the first time I've seen this issue before. How is this the first time I've used a copy ctor or = operator on an object with a reference.... anyway, thanks. – tanks_____tanks Aug 12 '20 at 13:06
  • 1
    Third option: define you own assignment operator that does the right thing (whatever that is -- depends on what the object is trying to do with that reference.) – Chris Dodd Sep 07 '20 at 16:59
  • @ChrisDodd also, whether such assignment operaror is implementable will also depend on what one is trying to do. In most cases it isn't, which is why I've left it out of the answer. – eerorika Sep 07 '20 at 17:07