Search code examples
c++sortingfriend

Sorting a std::vector with a compare functor which has access to class members


I want to sort out a vector using std::sort with self-defined comparison function/functor. Inside this function I always want to have access functions or variables defined within the class.

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);
        }
    };
}

Inside function1:

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

So instead of using "return (p1 < p2)", I want to have access to fixedpoint and maybe DistanceBetweenTwoPoints() function. Is this possible (i.e. using friend identifier somehow)?

Can anybody show me how to do this? Thanks.


Solution

  • As a nested type, CompareDistanceToGoal has access to all members of MainClass; there's no need to declare it a friend. (Although this is a moderately recent change to the language; a compiler that doesn't implement C++11 might need a friend declaration, friend CompareDistanceToGoal;, to match modern behaviour).

    However, since these members are non-static, you can't do anything with those members unless you provide a MainClass object. Perhaps you want to make them static; or perhaps you want to "capture" an object:

    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));