A set of pointers is reporting that it "contains" a brand-new object, even though this object was just created, and has a memory address which differs from those already in the set.
#include <iostream>
#include <set>
#include <vector>
using namespace std;
class foo {
public:
int x;
foo(int x) : x(x) {}
};
int main() {
vector<foo> my_vector;
set<foo*, bool (*)(foo*, foo*)> my_set([](foo* left, foo* right) { return left->x < right->x; });
my_vector.reserve(10);
for (int i = 0; i < 10; i++) {
my_vector.emplace_back(i);
my_set.emplace(&my_vector[i]);
}
foo temp(4);
if (my_set.count(&temp))
cout << "But why?" << endl;
return 0;
}
This behavior DOES NOT occur if temp
is initialized using an integer outside the range [0, 10). It's as if the integer x
is being used to determine equality, as opposed to just priority / precedence.
The behavior I want is that distinct objects (i.e., with distinct memory locations) always be treated as distinct objects in the set, and that the objects' values x
be used to order the elements. How do I achieve this behavior? Thanks.
Thanks all for the comments. Here is a solution that achieves the desired behavior:
int main() {
set<foo*, bool (*)(foo*, foo*)> my_set([](foo* left, foo* right) {
if (left->x == right->x)
return std::less<foo*>{}(left, right);
return left->x < right->x;
});
// ....
return 0;
}
EDITED to reflect @Igor Tandetnik's helpful comment!