【问题标题】:Can I extend std::map::lower_bound to search on non-key_type arguments?我可以扩展 std::map::lower_bound 以搜索非 key_type 参数吗?
【发布时间】:2019-05-31 19:25:25
【问题描述】:

这是我的情况的说明。我有一个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_bound 和map::upper_bound 只接受key_type(即Key)参数。我无法编译 std::lower_bound,我看到它需要 LegacyForwardIterator,但我很难解释这个规范。

就我的地图的Key 排序而言,Key 与Category 具有兼容的排序,即:k&lt;c 当且仅当k.category&lt;c,所以我的要求似乎合乎逻辑。

在实际情况下,Key 类更复杂,分离质量/类别组件(为了使用map&lt;category,map&lt;quality,value&gt;&gt; 解决方案)实际上并不能奏效,以防万一想。

如何在我的地图中找到其键等于某个非键值的元素范围的下限(和上限)?

【问题讨论】:

    标签: c++ stl stdmap lower-bound


    【解决方案1】:

    C++14 引入了透明比较器的概念,可以将find、lower_bound、upper_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

    【讨论】:

      猜你喜欢
      • 2020-06-15
      • 1970-01-01
      • 2012-04-29
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多