Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::set difference with self defined type

I've defined my own struct like

struct element {

int id;
float value;
}

and I'm using it with std::set. I want to use the set_difference algorithm (like already mentioned in a previous question for determining the difference of two sets. When I try to invoke the code, compilation stops with the following error message:

/usr/include/c++/4.2.1/bits/stl_algobase.h:268: error: passing 
'const element' as 'this' argument of 'element& element::operator=(const element&)' 
discards qualifiers

A minimal example may look like this:

std::set<struct element> s1;
std::set<struct element> s2;
std::set<struct element> s3;

element e1 = { 1, 11.0 };
element e2 = { 2, 22.0 };
element e3 = { 3, 33.0 };

s1.insert(e1);
s1.insert(e2);
s2.insert(e2);
s2.insert(e3);

set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), s3.begin());
like image 997
Eric Avatar asked Dec 16 '22 06:12

Eric


1 Answers

set_difference(s1.begin(), s1.end(), s2.begin(), s2.end(),
               std::inserter(s3, s3.begin()));
//             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Example: http://ideone.com/B4Cc1

By putting s3.begin() as the output iterator, you would mean that you want to overwrite the front region of the set with the set difference. Overwriting requires the size of set being larger than the result, which is obviously not true most of the time; even if the set is not empty, you can't use s3.begin() as output because the iterator is read-only (otherwise it would destroy the sorted order).

OTOH, std::inserter(x, cit) means that, whenever this output iterator is assigned (*it = y), the insert method will be called (x.insert(cit, y)), which is what you really want: populate a set from empty.

like image 146
kennytm Avatar answered Dec 30 '22 19:12

kennytm