【问题标题】:How does std::set and std::unordered_set construct elements in place with emplace()?std::set 和 std::unordered_set 如何使用 emplace() 构造元素?
【发布时间】:2019-09-23 11:28:07
【问题描述】:

两个容器的文档都说 emplace() 函数在原地构造元素,但是在构造元素之前它们如何知道新元素的位置?

例如,unordered_set 根据元素的哈希值放置元素。 unordered_set在构造之前如何知道元素的hash值?

我想也许 emplace 函数是用来获取右值,计算新元素的位置并移动对象,但是 insert() 可以做到同样的事情。

【问题讨论】:

    标签: c++ c++11 stl set emplace


    【解决方案1】:

    它在规范中没有明确说明它是如何工作的,但通常会发生一个数据结构内部节点对象(包含该值的 rb-tree 节点或哈希桶节点)将从参数构造,然后节点将被链接到数据结构中(对于集合到 rb-tree,对于 unordered_set 到哈希桶),并且如果值已经存在(所以没有添加),节点对象将被销毁。

    【讨论】:

    • 所以数据结构基本上保存了一个指向对象的指针,而不是像 std::vector 那样保存对象,对吗?如果是这种情况,我还有另一个问题:在重新平衡树/重新散列的情况下,我知道迭代器无效,但是指向元素的实际指针呢?它们仍然有效吗?
    • @SweeneyTodd 如果您还有其他问题,请将其作为另一个问题提出 - 或者在这种情况下,只需阅读 stackoverflow.com/q/6438086/560648(是的,他们会这样做)
    • 数据结构(用于集合的二叉树,用于 unordered_set 的开放哈希表)包含大量指向内部节点对象的指针。阅读它们以了解更多信息——rb-tree、open hash table with separate chaining。不要对“开放寻址”意味着“封闭哈希”这一事实感到困惑。
    • @SweeneyTodd:“在重新平衡树/重新散列的情况下,我知道迭代器无效”——这是错误的;根据规范 (23.2.4.1.9):“insert 和 emplace 成员不应影响迭代器的有效性和对容器的引用,并且擦除成员应仅使迭代器和对被擦除元素的引用无效。”
    • @ChrisDodd 我认为这是为了 std::set。对于 unordered_set,“如果由于插入而发生重新散列,则所有迭代器都将失效。”表示 here。
    猜你喜欢
    • 2021-05-30
    • 2015-10-11
    • 1970-01-01
    • 2011-01-25
    • 2014-08-10
    • 1970-01-01
    • 2013-03-26
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多