std::map 使用自定义密钥
std::map with custom key
我想使用具有以下自定义键的标准地图:
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::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));
}
但它带来了将成员压入可迭代容器的开销。如果您不想要那样,您可能必须自己重新实现一个字典序比较。
如果您不关心具体的顺序,只想满足排序的要求,一个常见且简单的模式是将 std::tie
与所有 class 成员一起使用比较实例,然后比较这些结果。
std::tie
创建对成员的引用的 std::tuple
,std::tuple
实现 operator<
按字典顺序比较其元素(在本例中为对象的成员) .
在你的情况下,使用成员 operator<
:
bool operator<(const ParserKey & other) const
{
return std::tie(compno_, resno_, precinctIndex_) <
std::tie(other.compno_, other.resno_, other.precinctIndex_);
}
在 C++20 中,您可以这样做:(在 class 范围内)
friend auto operator<=>(const ParserKey &, const ParserKey &) = default;
别忘了#include <compare>
。
这将为您提供所有 6 个关系运算符:==
、!=
、<
、<=
、>
、>=
、执行词典比较(与@FrançoisAndrieux 的回答相同)。
我想使用具有以下自定义键的标准地图:
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::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));
}
但它带来了将成员压入可迭代容器的开销。如果您不想要那样,您可能必须自己重新实现一个字典序比较。
如果您不关心具体的顺序,只想满足排序的要求,一个常见且简单的模式是将 std::tie
与所有 class 成员一起使用比较实例,然后比较这些结果。
std::tie
创建对成员的引用的 std::tuple
,std::tuple
实现 operator<
按字典顺序比较其元素(在本例中为对象的成员) .
在你的情况下,使用成员 operator<
:
bool operator<(const ParserKey & other) const
{
return std::tie(compno_, resno_, precinctIndex_) <
std::tie(other.compno_, other.resno_, other.precinctIndex_);
}
在 C++20 中,您可以这样做:(在 class 范围内)
friend auto operator<=>(const ParserKey &, const ParserKey &) = default;
别忘了#include <compare>
。
这将为您提供所有 6 个关系运算符:==
、!=
、<
、<=
、>
、>=
、执行词典比较(与@FrançoisAndrieux 的回答相同)。