【问题标题】:C++ container for storing sorted unique values with different predicates for sorting and uniqueness用于存储排序唯一值的 C++ 容器,具有用于排序和唯一性的不同谓词
【发布时间】:2014-12-23 10:10:11
【问题描述】:

我有一个包含 2 个字段(例如 A 和 B)的记录。如果它们的 As 相等,则应将记录的 2 个实例视为相等。另一方面,记录实例的集合应按 B 字段排序。

是否有像 std::set 这样的容器,它可以用两个不同的谓词定义,一个用于排序,一个用于唯一性,所以我可以避免显式排序而只附加元素?如果不是,如何解决?

问候,

【问题讨论】:

  • 为什么不使用std::set 并在record::Boperator== 方面实现operator< record::A
  • @TheParamagneticCroissant 因为std::set 根本不使用==?这意味着它将允许 OP 的语义重复元素。
  • @Angew cppreference tells me: "Key 必须满足EqualityComparable 的要求",那有错吗?
  • 乍一看,std::set 所需的订购条件是否能满足您施加的条件。它需要strict weak ordering,除其他外,它要求if !((a<b) || (b<a)) then a == bstd::set 中的元素标识是这样定义的。如果你能设法将你的限制硬塞到该任务中,那就太好了,但看起来你不能立即做到。
  • @TheParamagneticCroissant 我不认为页面不正确。您提供的链接特别提到要使用operator ==operator != 两个std::set 对象Key 必须是 EqualityComparable。这并不意味着它本身就是std::set 的内在要求。

标签: c++ sorting boost stl stdset


【解决方案1】:

标准库中没有任何内容可以直接支持您的用例。不过,您可以为此目的使用Boost.MultiIndexContainer。像这样的:

typedef multi_index_container<
  Record,
  indexed_by<
    ordered_non_unique<member<Record, decltype(Record::B), &Record::B>>,
    hashed_unique<member<Record, decltype(Record::A), &Record::A>>
  >
> RecordContainer;

(为了简洁起见,代码假定正确的标题和using namespace 指令)。

这个想法是创建一个具有两个索引的容器,一个将保证基于B 的排序,另一个将保证基于A 的唯一性。代码中的decltype() 当然可以替换为AB 的实际类型,你知道,但我不知道。

索引的顺序有点重要,因为为方便起见,容器本身提供与其第一个索引相同的接口。不过,您始终可以使用 container.get() 访问任何索引。

该代码并非旨在作为复制和粘贴解决方案,而是作为起点。您可以添加自定义、索引标签等。有关详细信息,请参阅 Boost 文档。

【讨论】:

    【解决方案2】:

    有没有像std::set这样的容器,可以定义两个不同的谓词,一个用于排序,一个用于唯一性

    std::set 根据您提供给它的排序标准定义特定元素是否唯一(默认情况下它使用 less)。无需显式传递另一个标准来检查元素的相等性。 不过话虽如此,您可以使用带有算法的谓词来检查 std::set 的元素是否相等。

    【讨论】:

      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 2011-09-11
      相关资源
      最近更新 更多