我可以扩展std :: map :: lower_bound来搜索非key_type参数吗?

时间:2019-01-05 12:56:57

标签: c++ stl stdmap lower-bound

这是我的情况的例证。我有一个std::map,我想找到第一个pair<key,value>,其中的键是等效键类的任何成员。

#include <map>

struct Category
{
    int foo;
    int bar;

    bool operator < (const Category & rhs) const;    
    bool operator > (const Category & rhs) const;
};

struct Key
{
    Category category;
    float quality;

    bool operator < (const Key & rhs) const
    {
        if (category < rhs.category)
            return true;
        else if (category > rhs.category)
            return false;
        else
            return quality < rhs.quality;
    }
};

struct Value {};

typedef std::map <Key, Value> Container;

Container::iterator find_low_quality
(
    Container & container,
    const Category & category
)
{
    return container.lower_bound (category);
}

Container::iterator find_high_quality
(
    Container & container,
    const Category & category
)
{
    // some checks need to be done, here omitted for brevity
    return --container.upper_bound (category);
}

这不起作用,因为map::lower_boundmap::upper_bound仅接受key_type(即Key)自变量。我无法编译std::lower_bound,我看到它期望LegacyForwardIterator,但是我很难解释这个规范。

就我的地图的Key而言,KeyCategory具有兼容的排序,即:k<c当且仅当k.category<c ,因此我的要求似乎合乎逻辑。

在实际情况下,Key类更复杂,并且如果可以的话,分离质量/类别组件(以使用map<category,map<quality,value>>解决方案)实际上是行不通的。你在想什么。

如何查找映射中其键等效于某些非键值的元素范围的下限(和上限)?

1 个答案:

答案 0 :(得分:1)

C ++ 14引入了透明比较器的概念,可以在其中使用findlower_boundupper_bound,...只要比较器明确选择采用这种行为,就可以与键类型进行比较。

根据您的情况,您需要添加一个自定义比较器

struct KeyComparator {
    // opt into being transparent comparator
    using is_transparent = void;

    bool operator()(Key const& lhs, Key const& rhs) const {
        return lhs < rhs;
    }

    bool operator()(Key const& lhs, Category const& rhs) const {
      return lhs.category < rhs;
    }

    bool operator()(Category const& lhs, Key const& rhs) const {
      return lhs < rhs.category;
    }
};

然后您需要在Container

中使用它
typedef std::map <Key, Value, KeyComparator> Container;

Live demo