0
votes
std::set<std::string> tradedSymbolSet; 
//..
// tradedSymbols is filled
//..
std::set<std::string> symbols;
//...
// symbols is filled
//..

std::set_difference(tradedSymbolSet.begin(), tradedSymbolSet.end(), 
        symbols.begin(), symbols.end(), diffSet.begin());

i get this compile error:

"error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Alloc>' (or there is no acceptable conversion)"

complaining about the set_difference function's usage. i couldn't get

2
did you forget to #include <string> ?Bathsheba
@Bathsheba : it is included..xyzt
Is diffSet const?Peter Wood
@Peter Wood: Good spot: that's where the smart money is.Bathsheba
@PeterWood Is diffSet an std::set? That's the most probably source of the problem.James Kanze

2 Answers

4
votes

I guess diffSet is std::set. If so, that is the problem : std::set stores elements as const objects, which means the object pointed to by std::set::iterator is read-only. You cannot write to it.

Use std::vector and std::back_inserter as:

std::vector<std::string> diff;

std::set_difference(tradedSymbolSet.begin(), tradedSymbolSet.end(), 
         symbols.begin(), symbols.end(), std::back_inserter(diff));

Once you have diff, you can create an object diffSet as:

std::set<std::string> diffSet(diff.begin(), diff.end());

Or, insert elements to an existing set as:

std::set<std::string> existingDiffSet;
//some code...

existingDiffSet.insert(diff.begin(), diff.end());

Hope that helps.

3
votes

You don't show the definition of diffSet, but if, as its name indicates, it is an std::set, you can't assign into it. The type of the object returned by the iterator is always const. There's also the question of whether the elements you are assigning to exist. If they don't (diffSet.size() less than the number of elements in the results), and the assignment were allowed, you'd have undefined behavior (but likely a crash); if they do, and the assignment was allowed, modifying an entry in the std::set would likely inviolate internal invariants regarding the order.

The usual use of the set functions is on sorted std::vector, with an insertion iterator for the output:

std::vector<std::string> tradedSymbols;
//  fill tradedSymbols
std::sort( tradedSymbols.begin(), tradedSymbols.end() );
std::vector<std::string> symbols;
//  fill symbols
std::sort( symbols.begin(), symbols.end() );

std::vector<std::string> diffs;
std::set_difference( tradedSymbols.begin(), tradedSymbols.end(),
                     symbols.begin(), symbols.end(),
                     std::back_inserter( diffs ) );

You can use std::set as well, but you'll have to change the inserter to std::inserter( diffs, diffs.end() ).

(Note that instead of sorting, you can keep the vectors sorted during insertion, by using std::lower_bound to find the point of insertion. If you're filling them in one go, however, using std::sort afterwards is probably more efficient.)