获取具有相等值的map元素范围

时间:2016-09-28 13:33:43

标签: c++ c++11 visual-c++ stl

我的地图声明为:

std::map< std::pair<int, int>, bool > allPositions; // essentially, keys are just 2D points

我需要获取其值为true

的元素范围

使用std::equal_range

auto range = std::equal_range(allPositions.begin(), allPositions.end(), true);

给出这些错误

  

错误C2672'operator __surrogate_func':没有匹配重载   功能发现xutility

     

错误C2893无法专门化功能模板'unknown-type   std :: less :: operator()(_ Ty1&amp;&amp;,_ Ty2&amp;&amp;)const'xutility

     

错误C2056非法表达xutility

     

错误C2672'operator __surrogate_func':没有匹配重载   功能发现算法

     

错误C2893无法专门化功能模板'unknown-type   std :: less :: operator()(_ Ty1&amp;&amp;,_ Ty2&amp;&amp;)const'算法

我认为我不需要谓词功能,因为std::pair已经超载operator <,否则地图代码将无法编译

那么如何使用std::equal_range for map来获得具有相等值的对的范围?

3 个答案:

答案 0 :(得分:1)

  

我需要获取true

的元素范围

你将不得不迭代地图以获得其值对为true的迭代器...我有一个工作示例Live On Coliru。这样的事情可以解除。

template<typename Map,
         typename Value    = typename Map::mapped_type,
         typename Compare  = std::equal_to<Value>,
         typename Iterator = typename Map::iterator>
std::vector<Iterator> equal_values(const Map& mp, const Value& val, Compare cmp = Compare()){
    std::vector<Iterator> rtn;
    for(auto iter = mp.begin(); iter != mp.end(); ++iter)
        if(cmp(iter->second, val))
            rtn.push_back(iter);
    return rtn;
}

或者,您可以使用Boost.BimapBoost.MultiIndex

答案 1 :(得分:0)

  

那么如何使用std :: equal_range for map来获得具有相等值的对的范围?

假设您有一张包含以下数据的地图:

{ {{0,0},false}, {{1,1},true}, {{2,2},false}, {{3,3},true} };

您期望true的回报等于什么?对于false

要使其正常工作,必须根据用于获取范围的条件对容器进行分区。 std::map绝对不是按值获取范围的容器。因此,您需要将数据或迭代器复制到不同的容器中并相应地对其进行排序,并使用该容器获取范围,或者通过过滤动态创建此类容器。或者您可以使用可以提供多个索引的boost::bimapboost::multi_index等容器。

答案 2 :(得分:-1)

所以假设你有一张地图:

using point = std::pair<int,int>;
std::map<point,bool> my_map;

让我们说你有一些价值观:

my_map = { {{0,0},false}, {{0,1},true}, {{1,0},true}, {{1,1},false} };

现在让我们看一下这个地图的第一个迭代器(取消引用时):

{{0,0},false}

当您使用std::equal_range(my_map.begin(), my_map.end(), true);时,您要求将true检查到取消引用的迭代器。但是,被引用的迭代器不是布尔值。它是一对点和一个布尔值 所以你可能想要尝试的是:

using map_iter = std::map<point,bool>::iterator; //is {point,bool}
auto range = std::equal_range(my_map.begin(), my_map.end(), [](map_iter& iter){
  return iter.second == true;
};

修改
只是为了澄清,这将解决编译器错误但不会解决映射值的逻辑错误(不一定)被排序,这样你就可以得到一对迭代器,它们定义一个包含所有匹配值的范围作为地图未按值排序