Bạn có thể sử dụng Boost.MultiIndex.
Bạn có thể xác định container như sau:
struct Connection
{
Employee emp;
Project prj;
};
typedef multi_index_container
<
Connection,
indexed_by
<
ordered_unique< identity<Connection> >,
ordered_non_unique< member<Connection, Employee, &Connection::emp> >,
ordered_non_unique< member<Connection, Project, &Connection::prj> >
>
> Relation;
Đây là một mẫu Runnable:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <string>
#include <functional>
namespace mi = boost::multi_index;
// these two type should implement std::less or operator<
typedef std::string Employee; // change to your definition
typedef std::string Project; // change to your definition
struct Connection
{
Employee emp;
Project prj;
Connection(const Employee& e, const Project& p): emp(e), prj(p) {}
bool operator <(const Connection& rhs) const
{
return std::less<Employee>()(emp, rhs.emp) ||
(emp == rhs.emp && std::less<Project>()(prj, rhs.prj));
}
};
struct employee {}; // for tag
struct project {}; // for tag
typedef mi::multi_index_container
<
Connection,
mi::indexed_by
<
mi::ordered_unique
<
mi::identity<Connection>
>,
mi::ordered_non_unique
<
mi::tag<employee>,
mi::member<Connection, Employee, &Connection::emp>
>,
mi::ordered_non_unique
<
mi::tag<project>,
mi::member<Connection, Project, &Connection::prj>
>
>
> Relation;
typedef Relation::index_iterator<employee>::type EmpIter;
typedef Relation::index_iterator<project>::type PrjIter;
int main()
{
Relation rel;
rel.insert(Connection("Tom", "sleeping"));
rel.insert(Connection("Jerry", "sleeping"));
rel.insert(Connection("Spike", "sleeping"));
rel.insert(Connection("Tom", "tormenting-partner"));
rel.insert(Connection("Jerry", "tormenting-partner"));
rel.insert(Connection("Spike", "playing-with-tyke"));
rel.insert(Connection("Tom", "fishing"));
rel.insert(Connection("Jerry", "playing-with-nibbles"));
rel.insert(Connection("Jerry", "tormenting-partner")); // duplicated
std::cout << "total connections: " << rel.size() << std::endl;
std::cout << "employees connected with sleeping project:" << std::endl;
std::pair<PrjIter, PrjIter> pit = rel.get<project>().equal_range("sleeping");
for (PrjIter it = pit.first; it != pit.second; ++it)
std::cout << '\t' << it->emp << std::endl;
std::cout << "projects connected with Jerry:" << std::endl;
std::pair<EmpIter, EmpIter> eit = rel.get<employee>().equal_range("Jerry");
for (EmpIter it = eit.first; it != eit.second; ++it)
std::cout << '\t' << it->prj << std::endl;
return 0;
}
kết quả:
total connections: 8
employees connected with sleeping project:
Tom
Jerry
Spike
projects connected with Jerry:
sleeping
tormenting-partner
playing-with-nibbles
+1, tôi sẽ nói wrap hai bản đồ trên một lớp mới, nhưng Bimap đã giải quyết được vấn đề, tìm kiếm tốt đẹp. –
tuy nhiên điều đó không cho phép các mối quan hệ nhiều-nhiều, phải không? Dường như với tôi rằng trong Bimaps, các khóa phải là duy nhất, ở cả hai bên, do đó, nó sẽ chỉ hoạt động cho các mối quan hệ một-một. (Xin lỗi vì đã đào bới ...) – Arthur