【问题标题】:Storing equal objects in a set在集合中存储相等的对象
【发布时间】:2021-06-03 18:47:04
【问题描述】:

我正在尝试做的事情:将set 中的元素按elem->value 排序,但仍然根据它们指向的内存地址识别它们是不同的元素。

#include <iostream>
#include <set>

using namespace std;

struct Node {
    int value;
    
    Node(int v) : value(v) {}
};

int main()
{
    Node* a = new Node(10);
    Node* b = new Node(10);
    Node* c = new Node(20);

    if (a == b) {
        cout << "a == b" << endl;
    }
    
    if (a == c) {
        cout << "a == c" << endl;
    }
    
    auto comparator = [](Node* lhs, Node* rhs) {
        return lhs->value < rhs->value;
    };

    set<Node*, decltype(comparator)> s(comparator);
    s.insert(a);
    s.insert(b);
    s.insert(c);
    
    cout << "after inserts, s.size() = " << s.size() << endl;
    
    s.erase(a);
    
    cout << "after erase, s.size() = " << s.size() << endl;
    
    delete(a);
    delete(b);
    delete(c);

    return 0;
}

由于a != b,我期望得到:

after inserts, s.size() = 3
after erase, s.size() = 2

但相反,我得到:

after inserts, s.size() = 2
after erase, s.size() = 1

使用lhs-&gt;value &lt;= rhs-&gt;value,我得到:

after inserts, s.size() = 3
after erase, s.size() = 3

使用multiset,我得到:

after inserts, s.size() = 3
after erase, s.size() = 1

【问题讨论】:

  • 听起来像是 XY 问题。您要解决的实际问题是什么?

标签: c++ c++11 set


【解决方案1】:

你应该使用内存地址进行抢七。

例子:

auto comparator = [](Node* lhs, Node* rhs) {
    return lhs->value < rhs->value ||
        (lhs->value == rhs->value && lhs < rhs);
};

【讨论】:

  • 使用std::less 比较不相关的指针。 en.cppreference.com/w/cpp/utility/functional/less "...任何指针类型的 std::less 特化产生实现定义的严格全序,即使内置 跨度>
  • @NathanOliver 根据N3337 5.9 关系运算符,它看起来像“未指定”,而不是“未定义”。
  • 是的,您需要改用std::less。这是std::set 的默认比较器,因此无需明确指定;在这种情况下,less 更多。
  • @MikeCAT unspecified,表示它不能满足严格偏序的要求。
  • @Sneftel 当不使用自定义比较器时,代码编译,但不起作用——对象不是由value 排序的。答案中的代码确实有效,我不关心指针的顺序,我只需要将它们彼此区分开来。
猜你喜欢
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 2019-12-02
相关资源
最近更新 更多