Using a std::unordered_set of std::unique_ptr

来源:互联网 发布:软件开发企业收入确认 编辑:程序博客网 时间:2024/05/20 20:21

转自:https://stackoverflow.com/questions/17851088/using-a-stdunordered-set-of-stdunique-ptr


====================================Ask====================================

 


Assume I have a set of unique_ptr:

std::unordered_set <std::unique_ptr <MyClass>> my_set;

I'm not sure what's the safe way to check if a given pointer exists in the set. The normal way to do it may be to call my_set.find (), but what do I pass as a parameter?

All I have from the outside is a raw pointer. So I have to create another unique_ptr from the pointer, pass it to find() and then release() that pointer, otherwise the object would get destructed (twice). Of course, this process can be done in a function, so the caller can pass the raw pointer and I do the conversions.

Is this method safe? Is there a better way to work with a set of unique_ptr?

===================================Answer==================================

     You can also use a deleter that optionally doesn't do anything.

template<class T>struct maybe_deleter{  bool _delete;  explicit maybe_deleter(bool doit = true) : _delete(doit){}  void operator()(T* p) const{    if(_delete) delete p;  }};template<class T>using set_unique_ptr = std::unique_ptr<T, maybe_deleter<T>>;template<class T>set_unique_ptr<T> make_find_ptr(T* raw){    return set_unique_ptr<T>(raw, maybe_deleter<T>(false));}// ...int* raw = new int(42);std::unordered_set<set_unique_ptr<int>> myset;myset.insert(set_unique_ptr<int>(raw));auto it = myset.find(make_find_ptr(raw));