小编典典

使用自定义 std::set 比较器

all

我正在尝试将一组整数中项目的默认顺序更改为字典顺序而不是数字,并且我无法使用 g++ 编译以下内容:

文件.cpp:

bool lex_compare(const int64_t &a, const int64_t &b) 
{
    stringstream s1,s2;
    s1 << a;
    s2 << b;
    return s1.str() < s2.str();
}

void foo()
{
    set<int64_t, lex_compare> s;
    s.insert(1);
    ...
}

我收到以下错误:

error: type/value mismatch at argument 2 in template parameter list for 鈥榯emplate<class _Key, class _Compare, class _Alloc> class std::set鈥�
error:   expected a type, got 鈥榣ex_compare鈥�

我究竟做错了什么?


阅读 70

收藏
2022-08-27

共1个答案

小编典典

1. 现代 C++20 解决方案

auto cmp = [](int a, int b) { return ... };
std::set<int, decltype(cmp)> s;

我们使用lambda
函数
作为比较器。像往常一样,比较器应该返回布尔值,指示作为第一个参数传递的元素是否被认为在它定义的特定严格弱排序中位于第二个之前。

在线演示

2.现代C++11解决方案

auto cmp = [](int a, int b) { return ... };
std::set<int, decltype(cmp)> s(cmp);

在 C++20 之前,我们需要将 lambda 作为参数传递给 set 构造函数

在线演示

3. 类似于第一个解决方案,但使用函数而不是 lambda

使比较器像往常一样布尔函数

bool cmp(int a, int b) {
    return ...;
}

然后以这种方式使用它:

std::set<int, decltype(cmp)*> s(cmp);

在线演示

或者这样:

std::set<int, decltype(&cmp)> s(&cmp);

在线演示

()4. 使用带有运算符的结构的旧解决方案

struct cmp {
    bool operator() (int a, int b) const {
        return ...
    }
};

// ...
// later
std::set<int, cmp> s;

在线演示

5.替代解决方案:从布尔函数创建结构

取布尔函数

bool cmp(int a, int b) {
    return ...;
}

并使用它制作结构std::integral_constant

#include <type_traits>
using Cmp = std::integral_constant<decltype(&cmp), &cmp>;

最后,使用结构作为比较器

std::set<X, Cmp> set;

在线演示

2022-08-27