我正在尝试将boost :: bimap用于我的一个要求。以下是示例代码
typedef bimap<
multiset_of< string >,
multiset_of< string >,
set_of_relation<>
> bm_type;
bm_type bm;
assign::insert( bm )
( "John" , string("lazarus" ) )
( "Peter", string("vinicius") )
( "Peter", string("test") )
( "Simon", string("vinicius") )
( "John", string("viniciusa") )
( "John", string("vinicius") )
我想做一些事情,为John和&amp;找到匹配的值。彼得,换句话说,约翰和约翰的价值观之间的交叉点。彼得为前:在这种情况下它将是(“vinicius”)。有人可以为它提供一些风头吗?
答案 0 :(得分:2)
这是我最初想出的:
template <typename Value = std::string, typename Bimap, typename Key>
std::set<Value> projection(Bimap const& bm, Key const& key)
{
std::set<Value> p;
auto range = bm.left.equal_range(key);
auto values = boost::make_iterator_range(range.first, range.second);
for (auto& relation : values)
p.insert(relation.template get<boost::bimaps::member_at::right>());
return p;
}
auto john = projection(bm, "John");
auto peter = projection(bm, "Peter");
std::multiset<std::string> intersection;
std::set_intersection(
john.begin(), john.end(),
peter.begin(), peter.end(),
inserter(intersection, intersection.end())
);
我认为它可以更有效率。所以我尝试使用Boost Range的适配器动态替换投影:
struct GetRightMember
{
template <typename> struct result { typedef std::string type; };
template <typename T>
std::string operator()(T const& v) const {
return v.template get<boost::bimaps::member_at::right>();
}
};
const GetRightMember getright;
std::cout << "Intersection: ";
// WARNING: broken: ranges not sorted
boost::set_intersection(
bm.left.equal_range("John") | transformed(getright),
bm.left.equal_range("Peter") | transformed(getright),
std::ostream_iterator<std::string>(std::cout, " "));
可悲的是 不起作用 - 可能是因为转换的范围没有排序。
所以我坚持使用更详细的版本(或重新考虑我的数据结构选择)。见 Live On Coliru