简体   繁体   English

指向std :: unordered_set中元素的指针/引用

[英]Pointer/Reference to element in std::unordered_set

im using a std::unordered_set to store my data object. 即时通讯使用std::unordered_set存储我的数据对象。 But now i want to create a pointer/reference to them, for example (without hash function ... ): 但是现在我想创建一个指向它们的指针/引用(例如,没有哈希函数...):

struct Node
{
  Node* parent;
  ...
};
std::unordered_set<Node> list;

is it possible to use a std::unordered_set<Node>::const_iterator ? 是否可以使用std::unordered_set<Node>::const_iterator Im not sure how to figure out this information if (without removing elements!) the iterator "ordering" changes ? 我不确定如果(不删除元素!)迭代器“排序”发生更改,如何找出此信息?

UPDATE with more details for better understanding: 更新以提供更多详细信息,以更好地理解:

Ive choosed std::unordered_set because of the constant lookup time. 我已经选择了std :: unordered_set,因为它的查找时间是恒定的。 To improve my C++ skills it would good to know what to change. 为了提高我的C ++技能,最好知道要进行哪些更改。

#include <iostream>
#include <string>
#include <stdint.h>
#include <vector>

#include <unordered_set>


struct Link;
struct Node
{
    uint32_t id;
    std::unordered_set<Link> link;

    Node(uint32_t id) : id(id)
    {
    };

    bool operator==(Node const& rhs)
    {
        return id == rhs.id;
    }
};

struct Link
{
    Node* parent;
    uint32_t param1; // ..... and more

    bool operator==(Link const& rhs)
    {
        return parent == parent.rhs && param1 == rhs.param1;
    }
}


namespace std
{
    template<> struct hash<Node>
    {
        size_t operator()(Node const& node) const
        {
            return hash<uint32_t>()(node.id);
        }
    };

    template<> struct hash<Link>
    {
        size_t operator()(Link const& link) const
        {
            return  hash<uint32_t>()(link.param1) ^ hash<Node>()(*link.parent);
        }
    };    
}

int main()
{
    std::unordered_set<Node> nodes;
    nodes.emplace( Node(1) );
    nodes.emplace( Node(2) );
    nodes.emplace( Node(3) );    
}

You can have pointers to the Node objects inside of the unordered_set . 您可以在unordered_set内部具有指向Node对象的指针。 However these pointer must be Node const* (ie, const ). 但是,这些指针必须是Node const* (即const )。

Even if an insertion is made to the unordered_set the pointers will not be invalidated. 即使对unordered_set进行了插入,指针也不会失效。 For example you could store these pointers in another unordered_set<Node const*> as: 例如,您可以将这些指针存储在另一个unordered_set<Node const*>如下所示:

std::unordered_set<Node, hasher> s{{1}, {2}, {3}};
std::unordered_set<Node const*> s_ptr;

for(auto &&i : s) {
  s_ptr.insert(&i);
}

Live Demo 现场演示

Iterators in unordered containers get invalidated when rehashing happens during an insert. 在插入期间进行重新哈希处理时,无序容器中的迭代器将失效。 I'd not try to predict or avoid rehashing. 我不会尝试预测或避免重新哈希。 As long as you don't insert new items, iterators stay valid. 只要您不插入新项目,迭代器就保持有效。 You may erase existing items. 您可以删除现有项目。

Note that values don't move even if rehashing occurs. 请注意,即使发生重新哈希处理,值也不会移动。 Pointers and references aren't invalidated until you remove that particular item. 在删除特定项目之前,指针和引用不会无效。 This means that you can do Node* parent or like that. 这意味着您可以执行Node* parent或类似操作。

It's unclear what is your data structure. 不清楚您的数据结构是什么。 I assume that you want to store nodes in an unordered_set (or several sets), and nodes have parent relation in addition to that. 我假设您想将节点存储在unordered_set (或多个集合)中,并且节点还具有parent关系。 It will work fine with pointers or references and not with iterators. 它将与指针或引用一起使用,而不与迭代器一起使用。 The only change you need is add one const: const Node *parent . 您需要做的唯一更改是添加一个const: const Node *parent If you need to change Node after inserting it in a set, you may either store them by pointer ( unique_ptr , etc.), or consider unordered_map with immutable part as a key. 如果您需要在将Node插入到集合中之后更改它,则可以通过指针( unique_ptr等)存储它们,也可以考虑将具有不可变部分的unordered_map作为键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM