【问题标题】:Convert boost::bimap to std::map将 boost::bimap 转换为 std::map
【发布时间】:2013-12-18 19:53:21
【问题描述】:

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

【问题讨论】:

    标签: c++ boost stdmap boost-bimap


    【解决方案1】:

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

    当取消引用 bimap 左视图迭代器时,返回类型与 std::pair

    签名兼容

    (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 ... 成语。

    @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

    【讨论】:

    • boost::transform_iterator 在这里可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 2015-09-03
    • 2018-11-06
    • 2012-06-25
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多