Create multiple indexes into a large collection of objects with smart pointers

前端 未结 2 1332
粉色の甜心
粉色の甜心 2021-01-16 18:15

I am creating multiple indexes (ie, that use different keys) into a large collection of objects. The objects can change, and the collection can shrink and grow. My thought

2条回答
  •  温柔的废话
    2021-01-16 18:51

    Here's one way.

    std::vector to hold the data items (to ensure that the addresses don't change when the vector resizes) and then containers holding reference_wrappers (copyable references) to make the indexes.

    compilable example:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    struct Thing {
        Thing(std::string name, int value)
        : _name { std::move(name) }
        , _value { value }
        {}
    
        const std::string& name() const {
            return _name;
        }
    
        void write(std::ostream& os) const {
            os << "{ " << _name << " : " << _value << " }";
        }    
    private:
        std::string _name;
        int _value;
    };
    
    inline std::ostream& operator<<(std::ostream& os, const Thing& t) {
        t.write(os);
        return os;
    }
    
    struct multi_index
    {
        using multi_by_name_index = std::multimap>;
    
        void add_thing(std::string name, int value) {
    
            // todo: checks to ensure that indexes won't be violated
    
            // add a new thing to the main store
            _main_store.emplace_back(new Thing{std::move(name), value});
    
            // store a reference to it in each index
            auto& new_thing = *(_main_store.back().get());
            _name_index.emplace(new_thing.name(), new_thing);
        }
    
        using multi_by_name_range = std::pair;
        multi_by_name_range get_all_by_name(const std::string name) const
        {
            return _name_index.equal_range(name);
        }
    
    private:
        std::vector> _main_store;
        std::multimap> _name_index;
    };
    
    using namespace std;
    
    int main()
    {
        multi_index mi;
    
        mi.add_thing("bob", 8);
        mi.add_thing("ann", 4);
        mi.add_thing("bob", 6);
    
        auto range = mi.get_all_by_name("bob");
        for( ; range.first != range.second ; ++range.first) {
            cout << range.first->second << endl;
        }
    
       return 0;
    }
    

    expected output:

    { bob : 8 }                                                                                                                             
    { bob : 6 }  
    

提交回复
热议问题