标准::使用自定义键映射



我想使用具有以下自定义键的标准映射:

struct ParserKey{
ParserKey(uint16_t compno,
uint8_t resno,
uint64_t precinctIndex) : compno_(compno),
resno_(resno),
precinctIndex_(precinctIndex)
{
}
uint16_t compno_;
uint8_t resno_;
uint64_t precinctIndex_;
};

但是,没有明显的方法来排序密钥。 是否可以订购这些密钥,或者是否需要其他关联集合?

如果您不关心特定顺序,只想满足排序要求,则常见且简单的模式是对比较实例的所有类成员使用std::tie,并改为比较这些结果。

std::tie创建对成员的引用std::tuplestd::tuple实现operator<,按字典顺序比较其元素(在本例中为对象的成员)。

在您的情况下,使用成员operator<

bool operator<(const ParserKey & other) const
{
return std::tie(compno_, resno_, precinctIndex_) < 
std::tie(other.compno_, other.resno_, other.precinctIndex_);
}

现场示例 https://godbolt.org/z/v433v54jz

您可以按照与std::lexicographical_compare相同的样式对这些整数施加任意的总顺序。

因此,懒惰的方法是:

// inside ParserKey ...
std::array<std::uint16_t,3> to_array() const {
return {compno_, resno_, precinctIndex_};
}
friend bool operator<(ParserKey const& lhs, ParserKey const& rhs) {
auto const l = lhs.to_array();
auto const r = rhs.to_array();
return std::lexicographical_compare(begin(l),end(l), begin(r), end(r));
}

但它承担了将成员压缩到可迭代容器中的开销。如果您不希望这样,则可能需要自己重新实现字典顺序比较。

在 C++20 中,您可以执行此操作:(在类范围内)

friend auto operator<=>(const ParserKey &, const ParserKey &) = default;

不要忘记#include <compare>.

这将给你所有6个关系运算符:==!=<<=>>=,执行字典顺序比较(与@FrançoisAndrieux的答案相同)。

最新更新