【问题标题】:User defined comparator for member of C++ classC++ 类成员的用户定义比较器
【发布时间】:2021-03-23 13:04:33
【问题描述】:

我有一个关于以下代码的快速问题:

#include <iostream>
#include <string>
#include <map>

using namespace std;

struct mySet{
    
    mySet(){
    }

    auto compare = [](int a, int b){ return a > b; };
    
    map<int, int, bool(*)(int, int)> myMap(compare);
    
    void insert(int x){
        if(myMap.find(x) == myMap.end()) myMap[x] = 1;
        else myMap[x]++;
    }
    
    void output(){
        for(auto p : myMap) cout << p.first << " " << p.second << endl;   
    }
};

int main()
{
  mySet thing;
  thing.insert(1);
  thing.insert(2);
  thing.insert(1);
  thing.output();
}

此代码引发了一个错误,我怀疑该错误与

    auto compare = [](int a, int b){ return a > b; };
    
    map<int, int, bool(*)(int, int)> myMap(compare);

我的理解是这不会编译,因为 compare 是一个需要实例才能被调用的类的成员。

如果我将此代码替换为

    static auto compare = [](int a, int b){ return a > b; };

它仍然无法编译,因为它至少需要一个 mySet 实例才能调用 compare。

我的问题是:

  1. 我的理解是否正确,或者 std::map 中的函数类型和比较器类型是否存在更险恶的情况?

  2. 是否有一个简单的解决方案来使用用户定义的比较器声明一个类的成员?我最简单的想法就是将成员声明为

std::map<int, int, bool(*)(int, int)> myMap;

然后将函数传递给构造函数

mySet( bool(*f)(int, int) ){
     map<int, int, bool(*)(int, int)> newMap (f);
     myMap = newMap;
}

只是好奇是否有更简单的解决方案,并试图更好地了解发生了什么。

感谢您的帮助。

【问题讨论】:

  • std::map&lt;int, int, std::greater&lt;int&gt;&gt;?
  • 您的insert 方法可以简化为myMap[x]++;operator[] 在密钥不存在时插入默认值(在您的情况下为 0)。
  • @Jarod42 是的,我想要一个更复杂的比较函数,但稍微简化了代码,这样更容易阅读。 @Peter 如果我写了bool(*compare)(int, int)compare 会被转换成bool(*)(int, int)吗?

标签: c++ class comparator


【解决方案1】:

您不能使用auto 声明非静态成员。

也不能对非整数类型的静态非 constexpr 数据成员进行类内初始化。

类内初始化不使用(),而是使用{}(或=)(以避免令人烦恼的解析问题)

所以你可以使用:

static constexpr auto compare = [](int a, int b){ return a > b; };
    
std::map<int, int, bool(*)(int, int)> myMap{compare};

Demo

或者在你的情况下,简单地说:

std::map<int, int, std::greater<int>> myMap;

Demo

【讨论】:

  • 感谢您的帮助!后续问题:我注意到如果我尝试在 cpp.sh 运行第一个演示,它不会编译并显示错误:error: 'constexpr const mySet::&lt;lambda(int, int)&gt; mySet::compare', declared using local type 'const mySet::&lt;lambda(int, int)&gt;', is used but never defined。是否发生了依赖于编译器的事情?
  • 出于多种原因需要 C++17。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多