1

I am working with set_union (included in algorithm.cpp) and sets in the STL library.

My sets hold objects of a custom class Vertex in which I have overloaded the operator=

Here is the Vertex class:

class Vertex {
public:
    City city;
    bool wasVisited;
    Vertex() {};
    Vertex(City c) {city = c; wasVisited = false;}
    double getWeightToVertex(Vertex v) {return city.getWeightWith(v.city);}
    Vertex& operator=(const Vertex&v) {
        if(this == &v)
            return *this;
        city = v.city;
        return *this;
    }
};

The problem resides in the following lines, included in the method of a different class.

for(int i=0; i<nEdges; i++) {
        Edge e = edges[i];
        Vertex start = vertexList[e.start];
        Vertex end = vertexList[e.end];
        if(sets[e.start].find(vertexList[e.end]) == sets[e.start].end()) { // The two vertices do not belong to the same set
           //Add the edge to our MST
            MST[nValidEdges] = e;
            nValidEdges++;
            //Get the union of vertex sets and insert it
            //in the corresponding place in the dynamic array
            set<Vertex> unionSet;
            set_union(sets[e.start].begin(), sets[e.start].end(), sets[e.end].begin(), sets[e.end].end(), unionSet.begin());
            sets[e.start] = unionSet;
        }
    }

That code generates a compile error in algorithm.cpp, more specifically in the code of set_union where it states that there is no viable overloaded operator= for two objects of type 'InputIterator'.

Here is the compiler error location:

template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator
__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
{
    for (; __first != __last; ++__first, ++__result)
        *__result = *__first; //Error Here: No Viable Overloaded '='
    return __result;
}

What am I missing here?

Joe
  • 2,386
  • 1
  • 22
  • 33
  • If you have questions involving compiler and/or linker errors, please include the errors, complete and unedited, in the question. Please edit your question to include the error. – Some programmer dude Dec 02 '13 at 12:12
  • 1
    By the way, that's not how you implement an assignment operator. First of all you have a memory leak, as you allocate a new `Vertex` but throw away the pointer. Then you don't actually do any assignment. The assignment operator assigns to `this`, then returns `*this`. – Some programmer dude Dec 02 '13 at 12:13
  • That is a seriously flawed operator=, oh Joachim said it faster and better. – RichardPlunkett Dec 02 '13 at 12:14
  • No reason with this class to even write an assignment operator. – john Dec 02 '13 at 12:14
  • There, updated the overloaded assignment code – Joe Dec 02 '13 at 12:19
  • Just drop the operator - the default one will work 110% fine. – Griwes Dec 02 '13 at 12:22

1 Answers1

2

Apart from the utterly bugged Vertex::operator= (which can just be deleted) the reason for your error is that you need to wrap unionSet in an inserter.

set_union(sets[e.start].begin(), 
    sets[e.start].end(), 
    sets[e.end].begin(), 
    sets[e.end].end(), 
    inserter(unionSet, unionSet.begin()));

Functions like set_union overate in 'overwrite' mode, that is they overwrite existing elements of the container you are writing to. If you want to add elements to an empty container you must use an adapter like inserter.

john
  • 85,011
  • 4
  • 57
  • 81
  • This eliminates the error, but generates a new one: No member named 'push_back'in 'std::__1::set, std::__1::allocator>' – Joe Dec 02 '13 at 12:19