Reputation: 577
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.
Upvotes: 1
Views: 1655
Reputation: 254501
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));
Upvotes: 3
Reputation: 106126
It's a bit hard to know what you're trying to do, but this seems to have as much chance of being what you want as anything else... note that MainClass
stores a fixedpoint
then provides a functor (no need for a nested class) which is then used by sort
. In the code below, it sorts the vector so elements closest to the MainClass
fixedpoint
are earlier in the vector
. See it running at 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';
}
Upvotes: 1
Reputation: 46598
you can capture value manually
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);
}
};
and use it
void MainClass::function1()
{
std::vector<float> V1;
std::sort(V1.begin(),V1.end(),MainClass::CompareDistanceToGoal(fixedpoint));
}
or if C++11 is available, use lambda to capture value
void MainClass::function1()
{
std::vector<float> V1;
std::sort(V1.begin(),V1.end(),[=](float p1, float p2){
return DistanceBetweenTwoPoints(fixedpoint,p1) < DistanceBetweenTwoPoints(fixedpoint,p2);
});
}
Upvotes: -1