Using a std::unordered_set of std::unique_ptr

后端 未结 4 2110
南旧
南旧 2021-01-07 16:40

Assume I have a set of unique_ptr:

std::unordered_set > my_set;

I\'m not sure what\'s the safe way to

4条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-07 17:21

    Note that the ability to do heterogenous lookups on standard containers is subject of some proposals.

    http://cplusplus.github.io/LWG/lwg-proposal-status.html lists

    • N3465 Adding heterogeneous comparison lookup to associative containers for TR2 (Rev 2) [Handle with N3573]
    • N2882 id.
    • N3573 Heterogenous extensions to unordered containers [Handle with N3465]

    Especially the latter looks like it would cover your use case.

    For now, here is an IMO not very pretty but working alternative workaround (O(n)):

    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    #include 
    
    struct MyClass {};
    
    template 
    struct RawEqualTo
    {
        RawEqualTo(T const* raw) : raw(raw) {}
    
        bool operator()(T const* p) const  
            { return raw == p; }
        bool operator()(std::unique_ptr const& up) const  
            { return raw == up.get(); }
    
      private:
        T const* raw;
    };
    
    
    using namespace std;
    int main()
    {
        std::unordered_set > my_set;
    
        my_set.insert(std::unique_ptr(new MyClass));
        my_set.insert(std::unique_ptr(new MyClass));
    
        auto raw = my_set.begin()->get();
    
        bool found = end(my_set) != std::find_if(begin(my_set), end(my_set), RawEqualTo(raw));
        assert(found);
    
        raw = new MyClass;
    
        found = end(my_set) != std::find_if(begin(my_set), end(my_set), RawEqualTo(raw));
        assert(!found);
    
        delete raw;
    }
    

    Warning It's also very inefficient, of course.

提交回复
热议问题