Harrand
Harrand

Reputation: 355

Why can't I use this parameter for Compare of std::sort()?

I'm trying to sort an std::vector of Meshes (Each with their own transform class and hence location) in ascending order of the distance of their location from the camera (A predefined Vec3).

== renderlist.hpp ==
//Includes & guard omitted

typedef std::vector<Object*> ObjectList;
class RenderList
{
public:
    RenderList(Object** objects, unsigned int numObjs, Camera& camRef);
    ObjectList getOrderedObjectList();
    void renderInOrder(Shader& master);
private:
    ObjectList unorderedList;
    Camera* cameraReference;
}
== renderlist.cpp ==
struct RenderListCompare
{
    Vec3 cp;
    RenderListCompare(Vec3 camPos)
    {
        cp = camPos;
    }
    bool compare(Object* obj1, Object* obj2)
    {
        Vec3 pos1 = obj1->getTransform().getTranslate();
        Vec3 pos2 = obj2->getTransform().getTranslate();
        return (pos1.distance(cp) > pos2.distance(cp));
    }
};

RenderList::RenderList(Object** objects, unsigned int numObjs, Camera& camRef)
{
    for(unsigned int i = 0; i < numObjs; i++)
    {
        this->unorderedList.push_back(objects[i]);
    }
    this->cameraReference = &camRef;
}

void RenderList::getOrderedObjectList()
{
    ObjectList temp = this->unorderedList;
    RenderListCompare rlc(this->cameraReference->getPos());
    std::sort(temp.begin(), temp.end(), rlc.compare);
    return temp;
}

The problem here is that I'm trying to use <algorithm>'s std::sort function's Compare parameter to tell it how to order the list (Via distance from camera position), but the struct I'm using for the comparison needed to be instantiated before I used its compare() function as a parameter.

An example similar to what I'm trying to do can be found at: cplusplus.com I am getting the following error upon compilation:

    renderlist.cpp: In member function 'ObjectList RenderList::getOrderedObjectList()': renderlist.cpp:32:49: error:
    no matching function for call to 'sort(std::vector::iterator, std::vector::iterator, )'
        std::sort(temp.begin(), temp.end(), rlc.compare);
                                               ^

My guess is that I've tried to mimic the link above to achieve a similar affect, but adding extra information to the struct before, which may have lead to a syntax error on my behalf.

Upvotes: 2

Views: 74

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385104

That's not how comparators work. Change your compare member function into an operator()

struct RenderListCompare
{
   RenderListCompare(const Vec3& camPos)
      : cp(camPos)
   {}

   bool operator()(const Object* obj1, const Object* obj2)
   {
      Vec3 pos1 = obj1->getTransform().getTranslate();
      Vec3 pos2 = obj2->getTransform().getTranslate();
      return (pos1.distance(cp) > pos2.distance(cp));
   }

private:
   const Vec3 cp;
};

… and just pass the RenderListCompare object to std::sort, instead of naming the member function yourself.

std::sort(
   temp.begin(),
   temp.end(),
   RenderListCompare(this->cameraReference->getPos())
);

Upvotes: 2

Related Questions