jeudi 24 août 2017

`std::unordered_map` without duplicating key data

I have a Person class, which has a name property (std::string).

I want to create a lookup-table, a std::unordered_map, so I can find a Person by their name. However, given a Person, I also want to be able to get their name.

This necessitates storing the name twice - once as the key of the map, and once inside the person object, as shown in my code below.

Since I have many Persons loaded into memory at once, I don't want the overhead of storing their names twice.

I've tried using references/pointers to the keys instead inside the Person class, but this creates problems as the map seems to reshuffle its data when it is modified, and the references become invalid.

I've also tried using std::unordered_set, but this means I need to construct a whole Person object every time I want to perform a lookup.

Is there any way for the key and value of a unordered map to share the same data?

#include <iostream>
#include <unordered_map>


class Person
{
    private:
        const std::string _name;

    public:
        Person( const std::string& name ) : _name( name )
        {
        }


        const std::string& get_name() const
        {
            return _name;
        }
};


int main()
{
    auto my_set = std::unordered_map<std::string, std::shared_ptr<Person>>();

    my_set.insert( { "alice", std::shared_ptr<Person>( new Person( "alice" )) } );
    my_set.insert( { "bob", std::shared_ptr<Person>( new Person( "bob" )) } );
    my_set.insert( { "charlie", std::shared_ptr<Person>( new Person( "charlie" )) } );

    std::cout << my_set.find( "bob" )->second->get_name() << std::endl;

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire