提问者:小点点

使用基于键的比较器的std::set


假设我有一组字符串(或映射),并且我想使用一个只比较前5个字符的自定义比较器。 所以“abcde”和“abcdef”在我的集合中是相同的。

typedef std::set<std::string, Cmp> MySet;

写CMP最好的方法是什么?

显而易见的方式是这样的:

struct Cmp
{
    bool operator()(const string& x, const string& y)
    {
        return (x.substr(0, 10) < y.substr(0, 10));
    }
}

问题是这段代码重复了.substr(0,10)。 在本例中,它相当短,但在一般情况下,它可能更长。 我想避免这种重复的代码。

通常,给定类型t1,t2和函数t2 key(t1&const),我希望有一组t1元素根据key(a)进行比较; 键(b),其中T2上的比较已经定义得很好。 写这个最好的方法是什么? 我曾考虑编写一个新的类KeyBaseSet,但这对于我的单个用例来说是过度设计的。 是否有某种方法使用std或boost来实现这一点?

我正在寻找类似于Python中排序时的key参数(https://docs.Python.org/3/howto/sorting.html#key-functions),或者Haskell中的compare`on`习惯用法(https://stackoverflow.com/a/2788262/351105)。


共1个答案

匿名用户

这个问题可以用高阶函数来解决。 本质上是一个接受T2键(常量t1&)函数并返回一个新函数的函数,该函数可用作std::set的比较器。 类似于:

auto make_comp(T key) {
    return [key](auto v1, auto v2){return key(v1) < key(v2);};
}

显然,这个例子需要泛型lambdas,但是应该也可以用模板结构来实现这一点:)