C++ std::set 唯一性覆盖

标签 c++ stl c++14

如何std::set<T>容器检查两个对象是否唯一?我尝试覆盖相等运算符 (==),但没有成功。

我想这样做的原因是我有一个 Person 类,如果他们有相同的名字(甚至可能是生日、地址等),我指定我的 Person 是同一个人。

ccpreference.com ,他们写了以下内容(我有点不清楚):

Everywhere the standard library uses the Compare concept, uniqueness is determined by using the equivalence relation. In imprecise terms, two objects a and b are considered equivalent (not unique) if neither compares less than the other: !comp(a, b) && !comp(b, a).

我假设,这个问题也会扩展到其他 STL 容器甚至算法(甚至可能扩展到整个 STL)。所以如果将来我想使用函数 std::find , 我会查找人的名字而不是对象本身。这是正确的吗?


编辑

我想添加一些示例代码。

// My operator overloading comparing two strings.
bool operator==(Node & rhs) const {
        return this->name.compare(rhs.name);
}

然后,在 UnitTest 中,我两次将同名对象添加到集合中。它被添加了两次(但根据 operator== 应该是相同的。

void test_adding_two_identical_nodes() {
    // The pool is a set<Node> inside
    model::Node_Pool pool{};
    pool.store_node(model::Node{"Peter"});
    pool.store_node(model::Node{"Peter"});
    // Should be only 1 because the same node should be added once into a set.
    ASSERT_EQUAL(1, pool.size());
}

最佳答案

std::set<T>不使用 == 进行比较.默认情况下,它使用 std::less<T> 进行比较。 .依次std::less<T>默认情况下,使用运算符 < .

实现集合的一种方法是覆盖 operator< ,像这样:

#include <set>
#include <cassert>

struct Person {
    const char *name;
    int uid;
};
bool operator<(const Person& a, const Person& b) {
    return a.uid < b.uid;
}
int main () {
   Person joe = {"joseph", 1};
   Person bob = {"robert", 2};
   Person rob = {"robert", 3};
   Person sue = {"susan", 4};

   std::set<Person> people;
   people.insert(joe);
   people.insert(bob);
   people.insert(rob);

   assert(people.count(joe) == 1);
   assert(people.count(bob) == 1);
   assert(people.count(rob) == 1);
   assert(people.count(sue) == 0);

   Person anonymous_3 = {"", 3};
   assert( std::strcmp(people.find(anonymous_3)->name, "robert") == 0);
}

或者,可以在声明 set 时将比较运算符作为模板参数传递.在上面的示例中,这可能是比较运算符:

struct Person_Compare {
    bool operator()(const Person& a, const Person& b) const {
        return a.uid < b.uid;
    }
};

还有 std::set声明可能如下所示:

std::set<Person, Person_Compare> people;

示例的其余部分没有变化。

关于C++ std::set 唯一性覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41469176/

相关文章:

c++ - 函数重载 C++ 指针

c++ - "public"和 "private"可见性修饰符的缩进

c++ - (c++) STL vector 的 STL vector

c++ - 基于模板参数类型的调用函数

c++ - 如果指针被初始化,它也会产生崩溃

c++ - Windows : Invalid function argument when run from GDB 上的 QT

c++ - 通过map key检查最后插入的项目是否存在

c++ - GDB 从返回的 whatis 中设置变量

c++ - 如何使用 range-v3 创建 view_facade

c++ - 在 C++ 中将通用构造函数分配给成员变量时的 std::move 或 std::forward