如何制作std :: weak_ptr的C ++ 11 std :: unordered_set [英] How to make a c++11 std::unordered_set of std::weak_ptr

查看:204
本文介绍了如何制作std :: weak_ptr的C ++ 11 std :: unordered_set的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的一套:set<weak_ptr<Node>, owner_less<weak_ptr<Node> > > setName;

工作正常.但我想将其更改为无序集合.但是,这样做时会出现大约六页的错误.任何想法如何做到这一点?

It works fine. But I would like to change it to an unordered set. However, I get about six pages of errors when I do that. Any ideas how to do that?

浏览完所有错误消息页面后,我发现可能会有所帮助的行.

After looking through all the pages of error messages I found to lines that might help.

/usr/include/c++/4.7/bits/functional_hash.h:60:7: error: static assertion failed: std::hash is not specialized for this type
/usr/include/c++/4.7/bits/stl_function.h: In instantiation of ‘bool std::equal_to<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::weak_ptr<Node>]’:

推荐答案

由于unordered_sets基于哈希,因此您必须提供哈希

Since unordered_sets are hash-based you have to provide a hash function object for the std::weak_ptr data-type.

如果您查看unordered_set模板参数

If you take a look at the unordered_set template-parameters

template<class Key,
    class Hash = std::hash<Key>,
    class Pred = std::equal_to<Key>,
    class Alloc = std::allocator<Key> >
    class unordered_set;

您会注意到std :: unordered_set为您提供了默认的std :: hash<>模板参数.但是由于std :: hash确实仅提供特定集的专业化功能数据类型,您可能必须提供自己的数据.

you'll notice that std::unordered_set provides you with a default std::hash<> template parameter. But since std::hash does only provide specializations for a specific set of data types, you might have to provide your own.

您引用的错误消息告诉您,不存在std :: weak_ptr<>的std :: hash<>专业化,因此您必须为此提供自己的哈希函数:

The error-message you quoted tells you, that no std::hash<> specialization for std::weak_ptr<> exists, so you have to provide your own hashing function for that:

template<typename T>
struct MyWeakPtrHash : public std::unary_function<std::weak_ptr<T>, size_t> {
   size_t operator()(const std::weak_ptr<T>& wp)
   {
      // Example hash. Beware: As zneak remarked in the comments* to this post,
      // it is very possible that this may lead to undefined behaviour
      // since the hash of a key is assumed to be constant, but will change
      // when the weak_ptr expires
      auto sp = wp.lock();
      return std::hash<decltype(sp)>()(sp);
   }
};

修改: 您还需要提供一个相等函数,因为没有为weak_ptr提供std :: equal_to. 通过在Stackoverflow上的平等比较std :: weak_ptr" ,采取一种可能的方式进行操作:

You also need to provide an equality function, since no std::equal_to for weak_ptr is provided. Taking a possible way to do this from "Equality-compare std::weak_ptr" on Stackoverflow:

template<typename T>
struct MyWeakPtrEqual : public std::unary_function<std::weak_ptr<T>, bool> {

   bool operator()(const std::weak_ptr<T>& left, const std::weak_ptr<T>& right)
   {
      return !left.owner_before(right) && !right.owner_before(left);
   }
};

所有这些结合在一起,我们得到了以下东西:

All combined this gives us the following:

std::unordered_set<std::weak_ptr<T>,
                   MyWeakPtrHash<T>,
                   MyWeakPtrEqual<T>> wpSet;

这篇关于如何制作std :: weak_ptr的C ++ 11 std :: unordered_set的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆