简体   繁体   中英

C++ unordered_map prevent memory reallocation for string keys

I am creating an unordered_map (C++ STL). The key is of type std::string and the value will be a pointer to objects of class X. the string key is actually the name of the object itself and will be stored as an instance variable in objects of that class. Is there a way for me to insert key,value pairs in unordered_map so that it does not allocate memory for the key?

I came up with the following solution ->

class X
{
public:
    const string name;
    X(char * c_name) : name(c_name) {}
};

unordered_map<string, X *> x_store;
X *a = new X("some_name"); 
x_store.insert(make_pair(a -> name, a))

but i believe the string object will be duplicated.

You cannot make unordered_map rely on your keys: it must store its own copy, because you could potentially change the string inside your X class.

However, you do not need to use a map - it looks like an unordered_set would be sufficient in your situation, with some custom equality and hash functions:

auto my_hash = [](X const& x) {
    return std::hash<std::string>()(x.name);
};
auto my_eq = [](X const& x, X const& y) {
    return std::equal_to<std::string>()(x.name, y.name);
};
std::unordered_set<X,my_hash,my_eq> mySet;

Now the key information is stored within the X object, which is stored inside mySet . Of course you cannot query a set by a string key, but you can use find and a "query object" to achieve the same result:

X query("abc"); // Set the name to "abc"
X *current = mySet.find(query);
if (current) {
    cout << current->name << endl; // Will print "abc"
} else {
    cout << "Not found" << endl;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM