对不同的类成员进行排序

Sort Over Different Class Members

本文关键字:排序 成员      更新时间:2023-10-16

我有一个类,其中包括几个类型为double的成员。

假设我需要创建一个函数,该函数根据类中的一个成员的值对类对象的向量重新排序。所以:

class myClass{
    ...
    public:
       double x, y, z;
    ...
 }
void SpecialSort_x(std::vector<myClass>& vec) {
    // re-order stuff according to values of vec[i].x
    ...
}

但是现在,我希望能够做同样的重新排序,但是根据类的其他成员的值(上面代码中的yz)。

除了将所有对x的引用更改为yz之外,我不想再制作两个与第一个相同的函数,我想制作一个单一的多态函数,可以根据myClass的任何成员对向量重新排序。

最好的方法是什么?

您可以将std::sort与lambda和指向成员的指针结合使用,从而:

#include <vector>
#include <algorithm>
class MyClass
{
public:
    double x, y, z;
};
typedef double MyClass::* Field;
void specialSort(std::vector<MyClass>& vec, Field field) 
{
    std::sort(vec.begin(), vec.end(), [field](const MyClass & a, const MyClass & b) -> bool
    {
        return a.*field < b.*field;
    });
}
int main()
{
    std::vector<MyClass> vec;
    Field member = &MyClass::x;
    specialSort(vec, member);
    return 0;
}

你也可以模板化排序使用:

template<class T>
void specialSort(std::vector<T>& vec, double T::* field)
{
    std::sort(vec.begin(), vec.end(), [field](const T& a, const T& b) -> bool
    {
        return a.*field < b.*field;
    });
}

鉴于这里的问题描述,我同意每个人提出的替代方法。

但是,如果确实需要访问在运行时选择的类成员,可以使用指向成员的指针类型。然而,通常有一种更优雅的方法来实现你想要的效果。

例如:

#include <iostream>
#include <vector>
struct X {
    double a;
    double b;
    double c;
};
void operate_on_member(const X& x, double X::*pm)
{
    std::cout << x.*pm << 'n';
}
int main()
{
    std::vector<X> xs {
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 }
    };
    for (const auto& x : xs)
        operate_on_member(x, &X::a);
    for (const auto& x : xs)
        operate_on_member(x, &X::b);
    for (const auto& x : xs)
        operate_on_member(x, &X::c);
}