Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ invalid comparator

I have a strange problem, maybe I'm missing something obvious but I can't fiugre out.

Here is the C++ code that throws the assert:

int compareByX(const Vector2D &a, const Vector2D &b)
{
    if (a.x < b.x) // if i put a.x > b.x nothing changes
        return -1;
    return 1;
}
int main(int argc, char *argv[])
{
    double pts[6] = { 5, 34, 3, 54, 10, 34 };
    std::vector<Vector2D> points;
    for (int i = 0; i < 6; i += 2)
        points.push_back({ pts[i],pts[i + 1] });
    std::sort(points.begin(), points.end(), compareByX);
}

what happens is that first point (3, 54) is tested against (5, 34), and then viceversa. At that point the assert (invalid comparator) is thrown. But as I see it its right to return -1 as 3 is lesser than 5 and then return 1 since 5 is more than 3...

Can you tell me what is wrong with this?

like image 356
deight Avatar asked May 31 '17 07:05

deight


2 Answers

The invalid comparator assert was thrown because the function returned -1 and 1, while std::sort takes only true or false in order to have a weak strict ordering.

By changing the function to:

bool compareByX(const Vector2D &a, const Vector2D &b)
{
   return a.x < b.x;
}

Everything works as expected.

In the end it was indeed a very obvious mistake.

like image 53
deight Avatar answered Nov 20 '22 03:11

deight


According to the reference for sort a comparator must:

comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than (i.e. is ordered before) the second. The signature of the comparison function should be equivalent to the following:

bool cmp(const Type1 &a, const Type2 &b);

I guess that what you really want is something as the following:

   std::sort(points.begin(), points.end(), 
         [] (const Vector2D& a1, const Vector2D&a2){return a1.x < a2.x;}
      );
like image 32
Davide Spataro Avatar answered Nov 20 '22 02:11

Davide Spataro