C++ 通过函数传递自定义比较器

C++ 通过函数传递自定义比较器,c++,comparator,C++,Comparator,我有一个带函数的类 MyClass::doStuff(std::vector<MyCustomData*> toSort) { ... myClass::SortByZ()是一个自定义比较器。 现在这是可行的,但我希望实现以下目标: 我有几个类,每个类都应该有自己的comparator functor来排序“MyCustomData”。例如,1班。。。应该有 class Class1 { struct SortData { bool operator ()(

我有一个带函数的类

MyClass::doStuff(std::vector<MyCustomData*> toSort) { ...
myClass::SortByZ()是一个自定义比较器。 现在这是可行的,但我希望实现以下目标:

我有几个类,每个类都应该有自己的comparator functor来排序“MyCustomData”。例如,1班。。。应该有

class Class1 {
    struct SortData {
        bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
        return lhs->something1 > rhs->something1;
        }
    };
    //...many more functions/vars
}
而Class2对于相同的数据类型有不同的comparator函子,例如

class Class2 {
    struct SortData {
        bool operator ()(MyCustomData *lhs, MyCustomData *rhs) {
        return lhs->something2 > rhs->something2;
        }
    };
    //...many more functions/vars
}
现在,我希望能够使用以下两种方法调用函数MyClass::doStuff(…)

doStuff(myData, Class1::SortData)

函数MyClass::doStuff(…)应该使用相应的排序顺序

我没有找到这样做的方法,有吗?我想要一个简单的解决方案(不必支持模板或任何东西)。如果需要的话,我愿意使用boost,但最好是没有boost的解决方案


我希望我能够描述我想要实现的目标?谢谢你的帮助

您必须制作
doStuff
模板:

template <typename Comparator>
void doStuff(std::vector<MyCustomData*> toSort, Comparator compare) {
   // ...
   std::sort(toSort.begin(), toSort.end(), compare);
   // ...
}
模板
void doStuff(标准::矢量排序,比较器比较){
// ...
std::sort(toSort.begin()、toSort.end()、compare);
// ...
}

此外,它可能希望引用第一个参数。实际上,它将对参数的副本进行排序,丢弃该副本,并保持调用方的向量不变;尽管这可能是您想要的。

使用函数模板,以便接受任何类型的比较函数(或函子):

模板
void doStuff(标准::矢量排序,比较器)
{
...
std::sort(toSort.begin()、toSort.end()、comparator);
...
}
...
doStuff(myData,Class1::SortData());
doStuff(myData,Class2::SortData());

这就是标准算法提供泛型的方式。

如果你的
向量
存储
MyCustomData
对象而不是指针,那么你的
SortData
函数应该有不同的签名:
bool操作符()(MyCustomData const&lhs,MyCustomData const&rhs)
。对不起,我不清楚这一点。向量存储指针,所以向量,所以函子签名有效。谢谢你的回答,也谢谢Luc!我又找到了两个可能对我有用的主意。是否可以使用参数(字符串)调用比较函数/函子?然后我调用doStuff(myData,“SortByThis”),比较器可以执行
bool操作符(…字符串SortByThis?…)(MyCustomData const&lhs,MyCustomData const&rhs){
…返回lhs.something.find[SortByThis]>second>rhs.something.find[SortByThis]->其次;
因为我是根据std::map something中的一些条目进行排序的。第二个想法是给结构一个变量
字符串SortByThis
并在操作符()中使用它,或者使结构成为一个类,实例化它,将SortByThis设置为我想要的字符串并使用它?我想我将尝试这三种方法。从软件工程的角度来看,有比另一种更好的方法吗?@Ela782:第二种方法是如何做到这一点。你不能更改比较器的函数调用运算符;这必须类似于
 bool操作符()(ta,tb);
没有额外的参数。但是你可以把数据成员放在比较器中,然后在操作符中使用它们。好的,所以我最后做了
类SortData{public:SortData(std::string sortType){this->sortType=sortType;};bool操作符()(MyCustomData*lhs,MyCustomData*rhs){return lhs->something.find(sortType)->second>rhs->something.find(sortType)->second;};private:std::string sortType;};
并用
std::sort调用它(toSort.begin()、toSort.end()、MyCustomData::SortData(“myortorder”))
我想这是比使用模板更好的解决方案?但是你的模板建议同样有用,非常感谢!很遗憾,我只能接受一个答案,因为你的答案是一样的,同样有用。而且你可能只会比较慢,因为你第一次输入了关于我的函子签名错误的注释。所以我不知道我该选谁精选,我是新来的,非常感谢你的帮助!@Ela782:别担心,我不会错过15点声望:)。通常,当一个问题有几个相同的答案时,通常会接受第一个答案。在这种情况下,@Mike的答案甚至稍微好一点,因为他提醒大家注意,
toSort
是按值传递的。我考虑过删除我的答案,但我将保留它,因为它提供了函数模板的示例使用。
doStuff(myData, Class2::SortData)
template <typename Comparator>
void doStuff(std::vector<MyCustomData*> toSort, Comparator compare) {
   // ...
   std::sort(toSort.begin(), toSort.end(), compare);
   // ...
}
template <typename Comparator>
void doStuff(std::vector<MyCustomData> toSort, Comparator comparator)
{
    ...
    std::sort(toSort.begin(), toSort.end(), comparator);
    ...
}
...
doStuff(myData, Class1::SortData());
doStuff(myData, Class2::SortData());