地图的密钥是否可以与部分值共享?
Can a map's key be shared with part of the value?
std::map
或std::unordered_map
的密钥可以与部分值共享吗?特别是如果密钥不是平凡的,比如像std::string
?
作为一个简单的例子,让我们以 Person 对象为例:
struct Person {
// lots of other values
std::string name;
}
std::unordered_map<std::string, std::shared_ptr<Person>> people;
void insertPerson(std::shared_ptr<Person>& p) {
people[p.name] = p;
// ^^^^^^
// copy of name string
}
std::shared_ptr<Person> lookupPerson(const std::string& name) const {
return people[name];
}
我的第一个想法是围绕指向该人的名字的包装器,但我无法弄清楚如何按名称进行查找。
就您的目的而言,std::map
可以被视为包含std::pair
的std::set
,该根据对的第一个元素进行排序(因此可以有效地访问(。
如果键元素和值元素部分相同,则此视图特别有用,因为这样就不需要人为地将集合的值和键元素分开(也不需要围绕选择键的值编写包装器(。
相反,只需要提供一个自定义排序函数,该函数适用于集并提取相关关键部分。
按照这个想法,你的例子变成了
auto set_order = [](auto const& p, auto const& s) { return p->name < s->name; };
std::set<std::shared_ptr<Person>, decltype(set_order)> people(set_order);
void insertPerson(std::shared_ptr<Person>& p) {
people.insert(p);
}
作为替代方案,您也可以在此处删除自定义比较并按共享指针中的地址对集合进行排序(支持<
,因此可以直接在集合中使用(:
std::set<std::shared_ptr<Person> > people;
void insertPerson(std::shared_ptr<Person>& p) {
people.insert(p);
}
在需要时用unordered_set
替换set
(通常您还需要提供合适的哈希函数(。
编辑:可以使用std:lower_bound
执行查找:
std::shared_ptr<Person> lookupPerson(std::string const& s)
{
auto comp = [](auto const& p, auto const& s) { return p->name < s; };
return *std::lower_bound(std::begin(people), std::end(people), s, comp);
}
演示。
编辑2:但是,鉴于这些或多或少丑陋的东西,您也可以遵循主要思想的路线,并在值周围使用一个小包装器作为键,例如
struct PersonKey
{
PersonKey(std::shared_ptr<Person> const& p) : s(p->name) {}
PersonKey(std::string const& _s) : s(_s) {}
std::string s;
bool operator<(PersonKey const& rhs) const
{
return s < rhs.s;
}
};
像(未经测试(一样使用它
std::map<PersonKey, std::shared_ptr<Person> > m;
auto sptr = std::make_shared<Person>("Peter");
m[PersonKey(sptr)]=sptr;
查找是通过
m[PersonKey("Peter")];
现在我比我的第一个建议更喜欢这个;-(
这是大卫海尔答案的另一种选择。
struct Person {
// lots of other values
std::string name;
}
struct StrPtrCmp {
bool operator()(const std::string* a, const std::string* b) const {
return *a < *b;
}
}
std::map<const std::string*, std::shared_ptr<Person>, StrPtrCmp> people();
void insertPerson(std::shared_ptr<Person>& p) {
people[&(p.name)] = p;
}
std::shared_ptr<Person> lookupPerson(const std::string& name) const {
return people[&name];
}
并进行一些编辑以使其与std::unordered_map
一起使用:
struct StrPtrHash {
size_t operator()(const std::string* p) const {
return std::hash<std::string>()(*p);
}
};
struct StrPtrEquality {
bool operator()(const std::string* a, const std::string* b) const {
return std::equal_to<std::string>()(*a, *b);
}
};
std::unordered_map<const std::string*, std::shared_ptr<Person>, StrPtrHash, StrPtrEquality> people();
相关文章:
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 允许从 std::map 的密钥窃取资源?
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 在没有密钥的情况下读取密文的剩余噪声预算
- 如何修复无效的API密钥,IP或操作权限错误?
- 所有可能的链接生成器与64位密钥
- 如何在unordered_map中更改密钥?
- 获取当前密钥状态?
- curl_easy_perform() 失败:SSL 对等证书或 SSH 远程密钥不正常
- 将密钥发送到非前台的游戏窗口
- 有哪些方法可以对基于 256 位密钥的矩阵进行加扰?
- 如何在精灵表上的两个不同部分之间来回切换,同时用户仍使用 SFML 持有密钥
- 如何将CNG密钥转换为OpenSSL EVP_PKEY(反之亦然)?
- 运行密钥密码解密知道密钥?
- 如何在 OpenSSL 中使用预共享密钥
- 如何在c++中跨不同的映射共享密钥
- 共享内存段密钥突然更改
- ECDH共享密钥在Crypto++和Android之间不匹配
- 地图的密钥是否可以与部分值共享?
- 从BCRYPT_SECRET_HANDLE导出共享密钥为字节数组