4

将 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;
}
4

1 回答 1

1

a 中的值bimap不能直接分配给 a 的 thos,map因为存在类型问题(忽略更明显的值 const-ness 问题):

当取消引用 bimap 左视图迭代器时,返回类型与 std::pair< const A, const B > 签名兼容

来源

和 :

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

这意味着不能保证您的 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 ... 成语。

@CharlesPehlivanian 在评论中指出了一个巧妙的解决方案(他可能也会提供作为答案),即使用boost::trasnform_iterator.

为此,您必须提供一个transformer仿函数(它不适用于原始 lambda,您必须使用带有operator()andresult_type或 a的结构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

于 2013-12-18T20:50:09.163 回答