Reference as key in std::map

Viewed 15022

Suppose some data structure:

typedef struct {
    std::string s;
    int i;
} data;

If I use the field data.s as key when adding instances of data in a map of type std::map<std::string&, data>, do the string gets copied? Is it safe to erase an element of the map because the reference will become invalid?

Also do the answers to these questions also apply to an unordered_map?

EDIT:

This is my current solution... but adding iterator to the map is UGLY:

typedef struct {
    const std::string* s;
    int i;
} data;

std::map<std::string, data> map;
typedef std::map<std::string, data>::iterator iterator;

// add an element to the map
iterator add_element(const std::string& s) {
    std::pair<iterator, bool> p = states.insert(std::make_pair(s, data()));
    iterator i = p.first;
    if(p.second) {
        data& d = (*i).second;
        d.s = &(*i).first;
    }
    return i;
}
5 Answers

Regarding your question about unordered_map, std::reference_wrapper will not work in the case.

std::reference_wrapper is not a default constructible class. To create a hasher, std::unordered_map needs type of the key to be a default constructible, copy assignable, destructible, and swappable class. See the std::hash.

You could try write your own reference_wrapper which would be a default constructible class, and use your class as the key type for a std::unordered_map specialization. To check whether your class satisfy each criterion mentioned above, use related functions from the type_traits library.

Related