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
Post a Comment