std::map::extract() 如何允许更改密钥?

How does std::map::extract() allow changing the key?

提问人:chiasmos 提问时间:2/9/2023 更新时间:2/9/2023 访问量:113

问:

我正在编写一个类似于 的模板类。目前,我正在努力实现一个等效于的函数。这应该返回一个具有自己的函数的节点句柄,该函数返回对键的非常量引用。因此,这允许更改与映射对象关联的键,从而避免移动映射对象。std::mapstd::map::extract()node_type::key()

std::map将其值公开为 ,但以某种方式允许通过对象更改对象。我不明白 STL 实现如何处理这个问题?我被引导相信它们包括const_cast转换,但我阅读的所有资源都非常不鼓励使用const_casts,因为害怕未定义的行为,尤其是在事后更改价值时。std::pair<const Key,T>Keynode_type

此资源调用“实现魔术”。

如何在不导致未定义行为的情况下实现?std::map::extract()

相关问题

C++ 模板 stl stdmap const-cast

评论

2赞 BoP 2/9/2023
实现可以通过简单地为特定用例定义未定义的行为来避免未定义的行为。这就是“实施魔术”。
0赞 Fareanor 2/9/2023
std::map可能不在内部处理,但更适合节点类型(我没有证据,这只是我的猜测)。std::pair<const Key, T>
0赞 gerum 2/9/2023
@Fareanor 但这意味着对该货币对的任何访问都需要该值的副本
0赞 chiasmos 2/9/2023
@Fareanor迭代器取消引用 ,这意味着必须有一个基础对象,不是吗?std::mapstd::pair<const Key, T>pair
1赞 BoP 2/10/2023
@chiasmos“实现魔术”是通过与编写编译器的人交谈而创造的。也许他们可以为您需要的 x 添加一个__builtin_x函数。或者让你有一个:-)#pragma magic make_this_work

答:

3赞 Caleth 2/9/2023 #1

如何在不导致未定义行为的情况下实现?std::map::extract()

你不能。该标准指定了在可移植 C++ 中无法实现的行为。

实现者(C++)将需要具有实现定义的额外保证,这些保证不需要向用户代码公开,以处理此要求。这通俗地称为“实现魔术”。

你可以做的是写一份提案,提交给委员会,然后把它投票选为未来的标准;这样就有一种机制可以做到这一点。C++20 中出现的隐式生存期类型与 .std::vector::data

评论

0赞 chiasmos 2/10/2023
有趣。这似乎是我正在寻找的答案,谢谢。您愿意在这里详细说明“可移植”c++ 的含义吗?我想这意味着实现是依赖于平台的,但为什么必须如此呢?
1赞 Caleth 2/10/2023
@chiasmos 当您以 a 开头时,以及一些有效的指针和对这些对象的引用,将其转换为 ,然后再变回 ,指针和引用仍然必须有效。有关对象生存期的规则不允许这样做。无论实现者可能想出什么解决方案,都必须与实现的其余部分相关联std::pair<const Key, Value>std::pair<Key, Value>std::pair<const Key, Value>