在实现constexpr无序Map的过程中,我试图理解std::unordered_map
规范的内部原理。我很难理解的一件事是,如何在不复制或移动Key
的情况下将std::pair<const Key, Value>
转换为std::pair<Key, Value>
。
查看GCC的实现(std::unordered_map
,hashtable.h
,hashtable_policy.h
),据我所知,std::unordered_map
在引擎盖下使用了_Hashtable
,它将节点中的项目直接存储为std::pair<const Key, Value>
。然而,当使用std::unordered_map
的 * 节点句柄 * 接口时,standard表示键是可修改的(这甚至是使用节点句柄的一个用例,以便能够在不必移动或复制值的情况下更改键):
key_type& key() const;
此外,例如当在Map上迭代时,需要能够具有对std::pair<const Key, Value>
的引用,因此如果将对存储为std::pair<Key, Value>
,则出现相同的问题(但是以相反的方式)。
显然,我的第一个直觉是简单地const_cast
去掉const,但据我所知,这是未定义的行为,因为原始数据是const(坦率地说,我甚至不知道是否有可能const_cast
在一对中的东西)。此外,在做constexpr实现的上下文中,const_cast
是不可行的。
只是为了确保,我还检查了,以下代码无法编译:
std::pair<int, int> p{1, 2};
std::pair<const int, int>& pref = p;
如果有人有更多关于如何实现这个的信息,或者熟悉GCC的实现,我将非常感激。
1条答案
按热度按时间fdbelqdn1#
它是通过命令这样做的。
在法律的的C中没有办法做这些函数所做的事情。但是,因为它们是C标准库的一部分,所以它们可以作弊。它们可以依赖于特定于实现的行为来做C++标准要求的事情。
你也可以依赖这些东西,但是你的程序的行为是未定义的,如果实现改变或者你使用不同的编译器,它会改变。