将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;
}发布于 2013-12-18 20:50:09
bimap的值不能直接分配给map的to,因为存在类型问题(忽略了更明显的值一致性问题):
当取消bimap左视图迭代器时,返回类型与std::pair< const A、const B>兼容签名。
(来源)
以及:
一个类型与其他类型兼容,如果它对函数和元数据具有相同的签名。先决条件、后条件和作业顺序不一定相同。
这意味着无法保证您的bimap value_type可分配或可复制到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 .成语。
在@CharlesPehlivanian的评论中,有一个简洁的解决方案(他可能也会提供答案),即使用boost::trasnform_iterator。
为此,您必须提供一个transformer函子(它不适用于原始lambda,您必须使用带有operator()和result_type的结构或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);以下是整个代码:
#include <boost/bimap.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <map>
int main(int argc, char const *argv[])
{
typedef boost::bimap<int, std::string> BiMapType;
typedef std::map<int, std::string> MapType;
typedef std::function<MapType::value_type (const BiMapType::left_value_type&)>
Transformer;
BiMapType bimap;
Transformer transformer_func = [](const BiMapType::left_value_type& elem)
{
return std::make_pair(elem.first, elem.second);
};
auto begin = boost::make_transform_iterator(bimap.left.begin(), transformer_func);
auto end = boost::make_transform_iterator(bimap.left.end(), transformer_func);
MapType map(begin, end);
return 0;
}http://coliru.stacked-crooked.com/a/8fae0d47ca4b72a1
https://stackoverflow.com/questions/20667187
复制相似问题