0

I have read duplicates but really didn't help me.

I am trying to reach next behaviour. Having a vector composed by pairs {Thing, set < Thing >} I want a final result of{Thing, newSetOfThing < Thing >} where that 'newSetOfThing' is the difference applied with every other sets in the vector but himself. Difference means to have all values but contained on other sets. I am using std::set_difference.

Giving a closer example with numbers.

vector = {[1, {3,4,5,7}], [2,{1,3,9}], [3, {1,2,12}]};

==>

vectorResult = {[1, {4,5,7}], [2, {9}], [3, {2,12} } 

Then my code looks like this:

class Thing {
public:
    Thing () {
    };
    ~Thing () {};
    int position; //id
    bool operator<(const Thing &Other) const;
};
bool Thing::operator<(const Thing &Thing) const
{
  return(Other.position<position);
}

//The original vector
vector<pair<Thing, set<Thing>>> pairWithSet;

// I fill vector here [...]

// variable I define to store partial results
set<Thing> differenceResult;
// Vector I want to fill for results
vector<pair<Thing, set<Thing>>> newPairWithSet;

// Operation 
for (pair<Thing, set<Thing>> currentPair : pairWithSet){
    Thing currentThing= currentPair.first;
    differenceResult = currentPair.second;
    for (int i=0; i<pairWithSet.size();i++) {
       if (pairWithSet[i].first.position != currentThing.position) {
    set_difference(differenceResult.begin(),
                   differenceResult.end(),
                   pairWithSet[i].second.begin(),
                   pairWithSet[i].second.end(),
                   differenceResult.begin());
}
         newPairWithSet.push_back(pair<Thing, set<Thing>>(currentThing, differenceResult));
}

I explain my objective to you have a point from where to go but at the end I think problem is more related of how wrong I am using set_difference operation and that I cant directly assign 'Thing'. So set_difference has not a way to check if they are the same. Because error is

binary '=': no operator found which takes a left-hand operand of type 'const Thing' (or there is no acceptable conversion

I say because maybe there are other errors to reach behaviour since I can't still debug until I solve problem with operator.

My question is if I need to declare that '=' operation and how. Or If I miss something and I need to perform by another way.

I can ensure problem is when I use set_difference, If I comment this part compiler does the task:

 set_difference(differenceResult.begin(),
                       differenceResult.end(),
                       pairWithSet[i].second.begin(),
                       pairWithSet[i].second.end(),
                       differenceResult.begin());

And I think is because at the end it is trying to perform an assignment to a const (because std::pair declaration?), as it says error (then obviously compiler does not know how to operate). So I have not clear how to perform it recursive set_difference.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 1
    *Where* do you get the error? And can you please copy-paste the *full* and *complete* error output, including any possible informational messages. – Some programmer dude Mar 09 '19 at 12:00
  • I have error in compile time. Error C2678 binary '=': no operator found which takes a left-hand operand of type 'const Thing' (or there is no acceptable conversion) | algorithm:4873 – FooBarExtension Mar 09 '19 at 12:04
  • 1
    @FooBarExtension Provide a [mcve] as required here please. – πάντα ῥεῖ Mar 09 '19 at 12:06
  • Are you sure you want to copy the thing and set of? Otherwise, you should use a reference: `for(std::pair<...>` **&** `: pairWithSet)` or simpler `auto&`. – Aconcagua Mar 09 '19 at 13:46

1 Answers1

1

set_difference writes results into place pointed by its 5-th argument. You are passing differenceResult.begin() what is wrong, because begin for set always returns const iterator. You cannot do write operation where a destination is object pointed by const iterator.

If you want to store Thing objects into set as result of set_difference algorithm, you can use std::inserter:

        set<Thing> res;  // CREATE EMPTY SET
        set_difference(differenceResult.begin(),
          differenceResult.end(),
          pairWithSet[i].second.begin(),
          pairWithSet[i].second.end(),
          std::inserter(res,res.begin())); // CREATE INSERT_ITERATOR WHICH INSERTS THINGS INTO RES

then you can copy res into newPairWithSet.

rafix07
  • 20,001
  • 3
  • 20
  • 33