c++ - STL set with custom comparator allows duplicate elements -


the following code simplified example produces problem.

a number of strings (char*) inserted set, many of non-unique. duplicate strings should detected , pointer original inserted should returned; however, doesn't happen , inserted string inserted again if not present.

the resulting set should consist of: "aa", "bb", "cc". output shows set ends with: "bb", "cc", "aa", "bb". changing string first inserted seems change duplicate 'allowed.'

the digit prefix on strings not used, added ensure each string has unique pointer; problem still exist without them.

using default comparator , non-prefixed strings work expected, compares pointers; prefixing strings results in unique pointers , strings inserted.

#include <iostream> #include <set> #include <cstring>  using std::cout; using std::endl; using std::set; using std::pair;  typedef set<const char*>::const_iterator set_iter;  struct cmp_op {     int operator() (const char* x,const char* y) const {         int r = strcmp(x,y);         //cout << "cmp: " << x << ((r)?((r>0)?" > ":" < "):" == ") << y << endl;         return r;     } };  int main() {     //first char ignored, ensures unique pointers     const char* a[] = {"1bb","2aa","3aa","4bb","5cc","6aa","7bb","8cc","9bb"};     const size_t n = sizeof(a)/sizeof(*a);      //using custom (strcmp) comparator     set<const char*,cmp_op> s;      (int i=0; i<n; ++i) {         cout << "insert(" << (void*)(a[i]+1) << "=" << (a[i]+1) << ")" << endl;         pair<set_iter,bool> r = s.insert(a[i]+1);         if (r.second) cout << "ok";         else {cout << "dup => " << (void*)(*r.first) << "=" << (*r.first);}         cout << endl << endl;     }      cout << n << " strings, " << s.size() << " unique:" << endl;     set_iter it=s.begin();     cout << (void*)(*it) << "=" << *it;     while (++it!=s.end())         cout << ", " << (void*)(*it) << "=" << *it;     cout << endl;      return 0; } 

i'm using mingw gcc 4.8.1 on windows; testing ubuntu produces same result.

your comparison function not implement strict weak ordering, because returns true whenever lhs not equal rhs. need change logic return true when 1 "less than" other. 1 example, seems natural choice:

return r < 0; 

note make intent clear, better return bool:

bool operator() (const char* x, const char* y) const  {   return strcmp(x, y) < 0; } 

Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -