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

新手上路,请多包涵

我正在尝试将一组整数中项目的默认顺序更改为字典而不是数字,并且我无法使用 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 ‘template<class _Key, class _Compare, class _Alloc> class std::set’
error:   expected a type, got ‘lex_compare’

我究竟做错了什么?

原文由 Omry Yadan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

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;

在线演示

原文由 diralik 发布,翻译遵循 CC BY-SA 4.0 许可协议

希望这会节省您的一些时间。你想知道的关于比较器的简单理论,

在 C++ 中,如果参数相等,比较器应该返回 false

原文由 Chethaka Uduwarage 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题