What does “operator = must be a non-static member” mean?

旧街凉风 提交于 2019-11-26 09:12:47

问题


I\'m in the process of creating a double-linked list, and have overloaded the operator= to make on list equal another:

template<class T>
void operator=(const list<T>& lst)
{
    clear();
    copy(lst);
    return;
}

but I get this error when I try to compile:

container_def.h(74) : error C2801: \'operator =\' must be a non-static member

Also, if it helps, line 74 is the last line of the definition, with the \"}\".


回答1:


Exactly what it says: operator overloads must be member functions. (declared inside the class)

template<class T>
void list<T>::operator=(const list<T>& rhs)
{
    ...
}

Also, it's probably a good idea to return the LHS from = so you can chain it (like a = b = c) - so make it list<T>& list<T>::operator=....




回答2:


Put that operator inside your class definition. It must be a member because operator= is special and you would not gain something by writing it as a non-member anyway. A non-member operator has two important main benefits:

  • Implicit conversions of the right and the left side of the operator invocation
  • No need to know about internals of the class. Function can be realized as non-member non-friend.

For operator=, both is not usable. Assigning to a temporary result of a conversion does not make sense, and operator= will need access to internals in most cases. In addition, a special operator= is automatically provided by C++ if you don't provide one (the so-called copy-assignment operator). Making it possible to overload operator= as a non-member would have introduced additional complexity for apparently no practical gain, and so that isn't allowed.

So change your code so that it looks like this (this assumes the operator= is not a copy-assignment operator, but assigning from a list<T> to something else. This isn't clear from your question):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

It's pretty standard that a operator= returns a reference to itself again. I recommend you to adhere to that practice. It will look familiar to programmers and could cause surprises if it would return void all of a sudden.




回答3:


If you overload an operator as a member function, you should use this template:

class A {
  A& operator=(const A& other) {
    if (this != &other) {
      ...
    }
    return *this;
  }
}

Three things to note:

  1. Check for self-assignment with the assignment operator (as above);
  2. The argument should be a const reference; and
  3. Return the result of the operation as a non-const reference where you return *this to allow chaining of operators.

You can also overload an operator external to the class. This isn't relevant to this example because you can't do it with the assignment operator but it's worth noting because in many cases it's superior to member functions. The typical form is:

class A {
  friend const A& operator+(const A& a, const A& b);
  ...
}
const A& operator+(const A& a, const A& b) {
  A& ret = ...
  return ret;
}

This one returns a const reference so you can't do this:

(a + b) = c



回答4:


From C++ Standard, "Binary Operators":

"A binary operator shall be implemented either by a non-static member function with one parameter or by a non-member function with two parameters"

It wants you to define this in a class, as a member, or make it a static method (in which case it should take two parameters (for both the lval and the rval).



来源:https://stackoverflow.com/questions/871264/what-does-operator-must-be-a-non-static-member-mean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!