Reputation: 1098
correct way to create look up maps for instances. I have a structure defined Node as follows
struct Node
{
int32_t id;
std::string name;
...
}
i want to create 2 look up maps, on based on id and another based on name. There are other attributes in the Node which also needs look up maps but those are dynamic so not every Node instance will have a look entry into those additional maps.
with just one look up map I was planning to create something like
typedef std::unoredered_map<int32_t, std::unique_ptr <Node> > NodesById;
I reason being just I can get this deleted by just erase
or [id] = new 'overwrite!'
operation and don't have to worry about it.
But then how can I add the same Node instance to say another map
typedef std::unoredered_map<std::string, std::unique_ptr <Node> > NodesByName;
I cannot put same Node instance into to unique_ptr. So my question is what is the correct way to store Node instances into multiple look up tables and still achieve smart memory management.
Upvotes: 0
Views: 103
Reputation: 136525
Use boost::multi_index
:
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <string>
#include <cassert>
struct Node {
int32_t id;
std::string name;
Node(int32_t id, std::string name)
: id(id)
, name(move(name))
{}
// Just to demonstrate that Node doesn't need to be copyable/moveable.
Node(Node const&) = delete;
Node& operator=(Node const&) = delete;
};
namespace mi = boost::multi_index;
using NodeSet = mi::multi_index_container<
Node
, mi::indexed_by<
mi::hashed_unique<mi::member<Node, int32_t, &Node::id>>
, mi::hashed_unique<mi::member<Node, std::string, &Node::name>>
>
>;
int main() {
NodeSet s;
s.emplace(1, "Alice");
s.emplace(2, "Bob");
assert(s.find(1)->name == "Alice");
assert(mi::get<0>(s).find(1)->name == "Alice"); // Same as above.
assert(mi::get<1>(s).find("Alice")->id == 1);
}
Storing by value is more efficient than storing unique_ptr
in there. And since NodeSet
doesn't require Node
to be copyable or moveable it is unnecessary to use unique_ptr
here.
Upvotes: 4