将boost :: bimap转换为std :: map

时间:2013-12-18 19:53:21

标签: c++ boost stdmap boost-bimap

将bimap转换为std :: map的明显方法似乎不起作用。低于正确/好的转换方式?有更好/更短的方式吗?

typedef boost::bimap<int, std::string> MapType;
MapType _bimap;
//Fill _bimap
MapType::left_map& lmap = _bimap.left;
//std::map<int, std::string> bmap(lmap.begin(), lmap.end()); //THIS DOESNT WORK
std::map<int, std::string> bmap;
BOOST_FOREACH(MapType::left_const_reference entry, lmap)
{
   bmap[entry.first] = entry.second;
}

1 个答案:

答案 0 :(得分:0)

来自bimap的值不能直接分配给map的thos,因为存在类型问题(忽略值的常见问题):

  

当bimap左视图迭代器被解除引用时,返回类型与std :: pair&lt;签名兼容。 const A,const B&gt;

source

并且:

  

如果类型与函数和元数据具有相同的签名,则该类型与其他类型签名兼容。前提条件,后置条件和操作顺序不一定相同。

这意味着无法保证您的bimap value_type可分配或可复制到map value_type。事实上它不是:

typedef boost::bimap<int, std::string> BiMapType;
typedef std::map<int, std::string> MapType;

BiMapType bimap;
BiMapType::left_value_type t1 = *(bimap.left.begin()); // Mandatory for compilation on my version at least
MapType::value_type t2(t1);

如果你尝试t2 = t1;

,那将会非常失败(同样的事情)

所以要么你找到一种方法来转换你的value_types,要么保留for_each / transform / copy ... idiom。

@CharlesPehlivanian在评论中发出了一个简洁的解决方案(他也可以提供答案),即使用boost::trasnform_iterator

为此,您必须提供transformer仿函数(它不适用于原始lambda,您必须使用包含operator()result_type或{{1}的结构})将输入迭代器值转换为输出值:

std::function

然后你只需用 typedef std::function<MapType::value_type (const BiMapType::left_value_type&)> Transformer; Transformer transformer_func = [](const BiMapType::left_value_type& elem) { return std::make_pair(elem.first, elem.second); }; 包装开始和结束迭代器:

boost::make_transform_iterator

以下是整个代码:

    auto begin = boost::make_transform_iterator(bimap.left.begin(), transformer_func);
    auto end = boost::make_transform_iterator(bimap.left.end(), transformer_func);

http://coliru.stacked-crooked.com/a/8fae0d47ca4b72a1