0

'left' is std::vector of std::set for each element in left(which is set), I am trying to do set union operation to another set by iterating over 'left'.

Why is the following code not working. I am trying to do set union of the two sets.

std::vector<std::set<int> > left(num_nodes);
//Both leftv and left are not empty ....there is some code here which fills them.
std::set<int> leftv, dummy; 

for(std::set<int>::iterator u = leftv.begin(); u != leftv.end() ;u++){
    dummy.insert(v);          //v is some integer
    std::set_union (left[*u].begin(), left[*u].end(), dummy.begin(), dummy.end(), left[*u].begin());
    dummy.clear();
}

Error /usr/include/c++/4.3/bits/stl_algo.h:5078: error: assignment of read-only location ‘__result.std::_Rb_tree_const_iterator<_Tp>::operator* with _Tp = int’

Utkrist Adhikari
  • 1,052
  • 3
  • 15
  • 42
  • 2
    Could you elaborate **what** isn't working. Compiler errors? Runtime crash? – πάντα ῥεῖ Jul 19 '13 at 15:19
  • 1
    Your problem isn't in the union, but rather the way you are trying to iterate. What are you trying to union together? (is leftv just supposed to be the union of all sets in left?) – IdeaHat Jul 19 '13 at 15:20
  • If that is all relevant code, than `leftv` is empty when the `for` loop is reached, so you have nothing to iterate over. – Angew is no longer proud of SO Jul 19 '13 at 15:21
  • Which two sets? If you mean leftv and dummy, that's not what is happening here. Your use of set_union is doing the union of some item from left (the vector of sets) with dummy. What *are* you trying to achieve here? – SteveLove Jul 19 '13 at 15:22
  • @SteveL leftv is just the source of index u. the sets for the union is element of left and another set dummy – Utkrist Adhikari Jul 19 '13 at 15:30
  • You simply can't use `std::set_union` that way. The `C++` standard (25.4.5.2 para 2) states: _Requires: The resulting range shall not overlap with either of the original ranges_. – Blastfurnace Jul 19 '13 at 15:45

1 Answers1

1

You are trying to overwrite the contents of a set, by giving left[*u].begin() as the output argument of set_union. The elements of a set cannot be modified, since their value determines their position in the set. Even if you could, you would need to grow the container to accommodate the extra elements, not simply overwrite the existing ones; and the output must not overlap with either input range. To summarise: you can't use set_union to insert the contents of one set into another.

If you want to add the contents of dummy to left[*u], then insert each element:

std::copy(dummy.begin(), dummy.end(), std::inserter(left[*u]));
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644