As is hopefully clear from the code below, I’d like to have a set of objects objectSet, each containing str1 and str2. The set is keyed on str1, and any new objects with an str1 already in the objectSet will not be added, but if this new object has a different str2, I want to keep track of the fact that I saw it in the str2Set
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <set>
#include <map>
using namespace std;
class Object {
public:
string _str1;
string _str2;
set<string> _str2Set;
bool operator<(const Object& b) const {
return _str1 < b._str1;
}
};
int main(int argc, char *argv[]) {
set<Object> objectSet;
Object o;
o._str1 = "str1";
o._str2 = "str2";
pair< set<Object>::iterator, bool> o_ret = objectSet.insert(o);
if (o_ret.second == false) { // key exists
int temp = (*o_ret.first)._str2Set.size(); // this is apparently fine
(*o_ret.first)._str2Set.insert(o._str2); // this results in the error
}
return 0;
}
Here is the compiler error:
set_test.cpp: In function ‘int main(int, char**)’:
set_test.cpp:31: error: passing ‘const std::set, std::allocator >, std::less, std::allocator > >, std::allocator, std::allocator > > >’ as ‘this’ argument of ‘std::pair, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = std::basic_string, std::allocator >, _Compare = std::less, std::allocator > >, _Alloc = std::allocator, std::allocator > >]’ discards qualifiers
I understand this has to do with const but I still can’t figure out exactly what the problem is or how to fix it. Just getting rid of the const doesn’t help.
As an alternative, I tried storing my Object’s in
map<string,Object> objectSet;
And, strangely enough, the following works just fine:
pair< map<string,Object>::iterator, bool> o_ret = objectSet.insert(pair<string,Object>(o._str1,o));
if (o_ret.second == false) { // key exists
o_ret.first->second._str2Set.insert(o._str2);
}
Of course, that means I have to store str1 twice, which I consider wasteful.
Thanks for your input.
Your design is flawed. You are using Object as a key to a set, but then you are attempting to modify the keys of your set. Of course you are only modifying parts of Object that don’t affect it’s use as a key, but the compiler doesn’t know that. You need to modify your design, your second version is fine to me, I wouldn’t worry about storing the string twice (normally, I don’t know your specific circumstances). Alternatively you could split your object so the key part and the value part are separated. Finally you could declare _str2set as mutable.