c++ - Can a map's key be shared with part of the value? -


can std::map's or std::unordered_map's key shared part of value? if key non-trivial, std::string?

as simple example let's take person object:

struct person {     // lots of other values     std::string name; }  std::unordered_map<std::string, std::shared_ptr<person>> people; void insertperson(std::shared_ptr<person>& p) {     people[p.name] = p;     //    ^^^^^^     //    copy of name string }  std::shared_ptr<person> lookupperson(const std::string& name) const {     return people[name]; } 

my first thought wrapper around name points person, cannot figure out how lookup name.

for purpose, std::map can considered std::set containing std::pair's ordered (and efficiently accessible) according first element of pair.

this view particularly useful if key , value elements partly identical, because not need artificially separate value , key elements set (and neither need write wrappers around values select key).

instead, 1 has provide custom ordering function works on set , extracts relevant key part.

following idea, example becomes

auto set_order = [](auto const& p, auto const& s) { return p->name < s->name; };  std::set<std::shared_ptr<person>, decltype(set_order)> people(set_order);  void insertperson(std::shared_ptr<person>& p) {     people.insert(p); } 

as alternative, here drop custom comparison , order set addresses in shared pointer (which supports < , can used directly in set):

std::set<std::shared_ptr<person> > people;  void insertperson(std::shared_ptr<person>& p) {     people.insert(p); } 

replace set unordered_set needed (in general need provide suitable hash function).

edit: lookup can performed using std:lower_bound:

std::shared_ptr<person> lookupperson(std::string const& s) {     auto comp =  [](auto const& p, auto const& s) { return p->name < s; };     return *std::lower_bound(std::begin(people), std::end(people), s, comp); } 

demo.


edit 2: however, given more-or-less ugly stuff, can follow lines of primary idea , use small wrapper around value key, like

struct personkey {     personkey(std::shared_ptr<person> const& p) : s(p->name) {}     personkey(std::string const& _s) : s(_s) {}      std::string s;     bool operator<(personkey const& rhs) const     {          return s < rhs.s;     } }; 

use (untested)

std::map<personkey, std::shared_ptr<person> > m; auto sptr = std::make_shared<person>("peter"); m[personkey(sptr)]=sptr; 

lookup done through

m[personkey("peter")]; 

now better first suggestion ;-)


Comments