Using Both Map and List for Same Objects

后端 未结 2 1550
抹茶落季
抹茶落季 2021-01-23 13:53

I\'m trying to use both a list and an unordered_map to store the same set of objects. I\'m new to C++, so still getting comfortable with iterators.

Say I have the follow

2条回答
  •  Happy的楠姐
    2021-01-23 14:04

    While Barry's approach is good, there is another one, more advanced and complicated. You can put your data object, (integer) key, and all bookkeeping bits in a single chunk of memory. Thus data locality will be improved and pressure on memory allocator will be less. Example, using boost::intrusive:

    #include 
    #include 
    #include 
    
    using namespace boost::intrusive;
    
    class Foo {
        // bookkeeping bits
        list_member_hook<> list_hook;
        unordered_set_member_hook<> set_hook;
    
        const int key;
        // some payload...
    
    public:
        // there is even more options to configure container types
        using list_type = list, &Foo::list_hook>>;
        using set_type = unordered_set, &Foo::set_hook>>;
    
        Foo(int key): key(key) {};
        bool operator ==(const Foo &rhs) const {
            return key == rhs.key;
        }
        friend std::size_t hash_value(const Foo &foo) {
            return std::hash()(foo.key);
        }
    };
    
    class Bar {
        Foo::list_type list;
    
        std::array buckets;
        Foo::set_type set{Foo::set_type::bucket_traits(buckets.data(), buckets.size())};
    
    public:
        template
        Foo &emplace(Args&&... args) {
            auto foo = new Foo(std::forward(args)...);
            // no more allocations
            list.push_front(*foo);
            set.insert(*foo);
            return *foo;
        }
        void pop(const Foo &foo) {
            set.erase(foo);
            list.erase(list.iterator_to(foo));
            // Lifetime management fun...
            delete &foo;
        }
    };
    
    int main() {
        Bar bar;
        auto &foo = bar.emplace(42);
        bar.pop(foo);
    }
    

    Measure how good are both algorithms on your data. My idea may give you nothing but greater code complexity.

提交回复
热议问题