std::set 指针中的虚假 "containment"
spurious "containment" in std::set of pointers
一组指针报告它“包含”一个全新的对象,即使这个对象是刚刚创建的,并且具有与集合中已有的不同的内存地址。
#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;
}
如果 temp
使用范围 [0, 10) 之外的整数初始化,则此行为 不会 发生。就好像整数 x
被用来确定 相等性 ,而不仅仅是优先级/优先级。
我想要的行为是不同的对象(即具有不同的内存位置)总是被视为集合中的不同对象,并且对象的值x
用于对元素进行排序。我如何实现这种行为?谢谢。
在std::set
中,对于两个值L和R,如果L<R
和R<L
都不相等,则认为它们相等。 "priority/ordering" 和相等没有分开,正如你所想的那样。
How do I achieve this behavior?
使用 std::set
以外的容器。例如,您保持排序的向量。
感谢大家的评论。这是实现所需行为的解决方案:
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;
}
已编辑以反映@Igor Tandetnik 的有用评论!
您可以先在 lambda 中检查是否相等。如果此检查失败,您可以计算顺序关系...
一组指针报告它“包含”一个全新的对象,即使这个对象是刚刚创建的,并且具有与集合中已有的不同的内存地址。
#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;
}
如果 temp
使用范围 [0, 10) 之外的整数初始化,则此行为 不会 发生。就好像整数 x
被用来确定 相等性 ,而不仅仅是优先级/优先级。
我想要的行为是不同的对象(即具有不同的内存位置)总是被视为集合中的不同对象,并且对象的值x
用于对元素进行排序。我如何实现这种行为?谢谢。
在std::set
中,对于两个值L和R,如果L<R
和R<L
都不相等,则认为它们相等。 "priority/ordering" 和相等没有分开,正如你所想的那样。
How do I achieve this behavior?
使用 std::set
以外的容器。例如,您保持排序的向量。
感谢大家的评论。这是实现所需行为的解决方案:
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;
}
已编辑以反映@Igor Tandetnik 的有用评论!
您可以先在 lambda 中检查是否相等。如果此检查失败,您可以计算顺序关系...