【问题标题】:find by key in std::set在 std::set 中按键查找
【发布时间】:2020-05-04 08:17:00
【问题描述】:

我与应该支持自定义比较操作的std::set 斗争。我的目标是能够仅使用 key 参数调用 find ,而无需先创建 set 类型的对象。像这样的:

#include <set>
#include <cstdint>
#include <vector>

class TestItem {
  public:
    std::uint64_t id;          // key
    std::vector<double> areas; // some other data
};

struct TestItemCompare {
    bool operator()(const std::uint64_t& lhs, const std::uint64_t& rhs) {
        return lhs < rhs;
    }
    bool operator()(const std::uint64_t& lhs, const TestItem& rhs) {
        return lhs < rhs.id;
    }
    bool operator()(const TestItem& lhs, const std::uint64_t& rhs) {
        return lhs.id < rhs;
    }
    bool operator()(const TestItem& lhs, const TestItem& rhs) {
        return lhs.id < rhs.id;
    }
};

int main() {
    std::set<TestItem, TestItemCompare> store;
    std::uint64_t id = 0;
    TestItem t;
    t.id = 0;

    auto it1 = store.find(t);    // compiles
    auto it2 = store.find(id);   // fails to compile

    return 0;
}

我认为这是可能的......

【问题讨论】:

  • 您确定不想改用std::map 吗?
  • 没有对您要求的支持仅在 C++20 中添加。为什么不简单地使用std::map&lt;int,std::vector&lt;double&gt;&gt;?正如上面评论中所建议的那样。
  • @ALX23z 透明比较在 C++14 中,您是否在考虑无序容器的透明哈希?
  • 关于 std::map 的优点。 set的优势是什么,真的吗?我认为它可能很有效,因为它不会复制密钥(我也需要数据结构中的密钥)。但在这种情况下,密钥并没有那么大。

标签: c++ stl set c++17


【解决方案1】:

这是可能的。但是您的比较器必须是透明的。而functor中的成员函数必须是const

struct TestItemCompare {
    using is_transparent = int; // actually any alias will do, void, custom type
    bool operator()(const std::uint64_t& lhs, const std::uint64_t& rhs) const {
        return lhs < rhs;
    }
    bool operator()(const std::uint64_t& lhs, const TestItem& rhs) const {
        return lhs < rhs.id;
    }
    bool operator()(const TestItem& lhs, const std::uint64_t& rhs) const {
        return lhs.id < rhs;
    }
    bool operator()(const TestItem& lhs, const TestItem& rhs) const {
        return lhs.id < rhs.id;
    }
};

【讨论】:

  • 这行得通!尽管如此,我还是使用了地图,因为我需要能够修改找到的项目(不是键,而是其他内容)。这可以通过地图完成,但不能通过集合完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 2021-10-23
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 2021-10-04
相关资源
最近更新 更多