使用可以访问类成员的比较仿函数对std :: vector进行排序

时间:2014-09-09 05:30:01

标签: c++ sorting friend

我想使用带有自定义比较函数/仿函数的std :: sort来排序向量。在这个函数中,我总是希望在类中定义访问函数或变量。

Class MainClass
{
    protected: // Variables
        float fixedpoint;

    protected: // Methods
        float DistanceBetweenTwoPoints(float,float);
        void function1();

    struct CompareDistanceToGoal : public std::binary_function<float,float,bool>
    {
        bool operator()(float p1, float p2)
        {
            // return ( p1 < p2);
            // I want to use the following code instead of the above
            return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
        }
    };
}

内部功能1:

void MainClass::function1()
{
    std::vector<float> V1;
    std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal());
}

因此,我不想使用&#34; return(p1&lt; p2)&#34;,而是希望能够访问fixedpoint和DistanceBetweenTwoPoints()函数。这是可能的(即以某种方式使用朋友标识符)?

有人能告诉我怎么做吗?感谢。

3 个答案:

答案 0 :(得分:3)

作为嵌套类型,CompareDistanceToGoal可以访问MainClass的所有成员;没有必要宣布它是朋友。 (虽然这是对语言的近期适度更改;未实现C ++ 11的编译器可能需要朋友声明friend CompareDistanceToGoal;,以匹配现代行为。)

但是,由于这些成员是非静态成员,除非您提供MainClass对象,否则您无法对这些成员执行任何操作。也许你想让它们变得静止;或者你想“捕捉”一个物体:

struct CompareDistanceToGoal // no need for that binary_function nonsense
{
    MainClass & mc;

    CompareDistanceToGoal(MainClass & mc) : mc(mc) {}

    bool operator()(float p1, float p2)
    {
        return mc.DistanceBetweenTwoPoints(mc.fixedpoint,p1) < 
               mc.DistanceBetweenTwoPoints(mc.fixedpoint,p2);
    }
};

std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal(some_main_class_object));

答案 1 :(得分:1)

很难知道你正在尝试做什么,但这似乎有更多机会成为你想要的东西......注意MainClass存储一个fixedpoint然后提供一个仿函数(不需要嵌套类),然后由sort使用。在下面的代码中,它对向量进行排序,以便最接近MainClass fixedpoint的元素在vector中更早。看到它在ideone.com运行。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

class MainClass
{
  public:
    MainClass(float fixedpoint) : fixedpoint_(fixedpoint) { }
    bool operator()(float p1, float p2) const
    {
        float d1 = DistanceBetweenTwoPoints(fixedpoint_,p1);
        float d2 = DistanceBetweenTwoPoints(fixedpoint_,p2);
        return d1 < d2 || d1 == d2 && p1 < p2;
    };

  protected: // Variables
    float fixedpoint_;
    static float DistanceBetweenTwoPoints(float a,float b) { return std::fabs(a - b); }
    void function1();
};

int main()
{
    std::vector<float> v { 1, 3, 4.5, 2.3, 9, 12 };
    std::sort(std::begin(v), std::end(v), MainClass(9.3));
    for (auto f : v)
        std::cout << f << '\n';
}

答案 2 :(得分:-1)

您可以手动捕获值

struct CompareDistanceToGoal : public std::binary_function<float,float,bool>
{
    float fixedpoint;

    CompareDistanceToGoal(float p) : fixedpoint(p) {}
    bool operator()(float p1, float p2)
    {
        return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
    }
};

并使用它

void MainClass::function1()
{
    std::vector<float> V1;
    std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal(fixedpoint));
}

或者如果C ++ 11可用,请使用lambda来捕获值

void MainClass::function1()
{
    std::vector<float> V1;
    std::sort(V1.begin(),V1.end(),[=](float p1, float p2){
        return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
    });
}