我有以下代码段
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
const size_t INF(numeric_limits<size_t>::max());
class nodehasher;
class node{
public:
int x,y;
unordered_set<node, nodehasher>::iterator neighbs[6]; //Issue Here
node(){}
node(int x_, int y_):x(x_),y(y_){}
void set(int x_, int y_){x = x_,y = y_;}
bool operator == (const node &n)const{
return x == n.x && y == n.y;
}
};
class nodehasher{
std::size_t operator()(node const& n) const{
std::size_t seed = 0;
hash_combine(seed, n.x);
hash_combine(seed, n.y);
return seed;
}
};
我似乎在声明指向节点本身内的类节点的迭代器时遇到了问题。
这导致了大量过于冗长的错误。
现在我意识到我可以创建我的neighbs数组,一个指向节点的数组, 但我想避免出于明显原因的指示
我使用它的典型简化方法是:
unordered_set<node, nodehasher> nodes;
void typical_use(node dest){
auto src_node = node(0,0);
int neighbcount = 0;
auto iter = dest.insert(node).first;
src_node.neighbs[neighb_count] = iter;
}
我显然可以将其转换为指针并执行:
src_node.neighbs[neighb_count] = &(*iter);
但是,没有办法避免指示我想做什么吗?
修改
由于许多注释和答案都指出容器元素的指针和迭代器在重新散列后都会失效 所以存储它们是一个坏主意。
我在想如果以下方式工作而不是unordered_set节点我会使用指向节点的unordered_set指针,就像这样
unordered_set<shared_ptr<node> > nodes;
另外,如果我知道节点的数量总是小于500,我可以放弃这整个哈希表的想法并使用一个数组,每次我必须搜索数组来检查节点是否是已经在那里了。
请指出哪种方法更好?
答案 0 :(得分:2)
标准容器需要完整的值类型。 node
在您使用它来实例化unordered_set<node, nodehasher>
时不是完整类型。
您可以使用Boost.Container,因为它们允许不完整的类型,但我没有看到散列容器(因此您必须使用set
)。
但是,您应该小心存储迭代器,因为,至少对于标准库中的unordered_
容器,它们可能会失效。
换汤不换药。引用(和指针)不会失效。