Search code examples
c++vectorassignment-operator

No viable '=' when using vector::erase


I am having some trouble with figuring out why I cannot seem to get std::vector::erase work with a vector of my own class objects. The following code throws a "No viable overloaded '='" error, and cannot figure out why after some extensive searching overflow/tutorialspoint/...

my class definition 'MyClass.hpp':

#include <string>
#include <vector>
class node;
class graph{
public:
    graph();
    std::vector<node> nodeList;
};

class node{
public:
    node(std::string name) : name(name){};
    void operator=(node& rhs);
    std::string name;
    std::vector<node> adjacent;
};

void node::operator=(node& rhs){
    name = rhs.name;
    adjacent = rhs.adjacent;
}

and my main file:

#include "MyClass.hpp"
int main(int argc, const char * argv[]) {
    node node1("root"), node2("leaf");
    node1.adjacent.push_back(node2);
    node2.adjacent.push_back(node1);
    node1.adjacent.erase(node1.adjacent.begin());
    graph myGraph;
    return 0;
}

Solution

  • std::vector::erase adds the requirement that the type T of the vector's elements must be move assignable. This means in particular that an expression like t = rv must have a return type of T & (reference to T) and a value of t (so the returned reference must reference the assigned to object).

    Your Node::operator= has return type void, thus violates above requirement. Further, the usual (and probably most reasonable) type signatures for copy / move assignment operators are as follows:

    T & operator=(T &&); // move assignment
    T & operator=(T); // copy assignment, pass by value
    T & operator=(T const &); // copy assignment, pass by const reference
    

    But, instead of fixing your operator, you should discard it all together! Your Node class does (should) not deal with ownership (the std::vector is doing this for you), thus per the rule of zero you should not provide a custom copy or move assignment operators (nor a destructor).