Vector ordering of objects

6

I'm making an application that sorts a vector of objects. These objects are Cartesian points, defined in the following class:

class CartesianPoint {
private:
    int x; // Coordinate X of a pin or a wire part on a cartesian plan
    int y; // Coordinate Y of a pin or a wire part on a cartesian plan

public:
    CartesianPoint();
    CartesianPoint(const CartesianPoint& orig);
    virtual ~CartesianPoint();

    int getX() const {
        return x;
    }

    int getY() const {
        return y;
    }

    CartesianPoint(int x, int y) :
    x(x), y(y) {
    }

To sort, I'm using the sort function as follows:

int main() 
{
    int i;
    CartesianPoint *a = new CartesianPoint(10, 13), *b = new CartesianPoint(32, 1), *c = new CartesianPoint(5, 29), *d = new CartesianPoint(12, 6), *e = new CartesianPoint(21, 100);
    CartesianPoint myPoints[] = {*a, *b, *c, *d, *e};

    std::vector<CartesianPoint> myvector(myPoints, myPoints+8);        

    // using function as comp
    std::sort(myvector[0], myvector.end(), myfunction); 

    // print out content:
    std::cout << "myvector contains:";
    for (i = 0; i < 8; i++)
        std::cout << ' ' << '(' << myvector[i].getX() << ',' << myvector[i].getY() << ')';
    std::cout << '\n';

    return 0;
}

where "myfunction" is the function that sorts the points in descending order with respect to x:

CartesianPoint* myfunction(CartesianPoint *a, CartesianPoint *b) {
    if(a->getX() > b->getX())
        return (a);
    else
        return (b);
}

The problem you are experiencing is the call of the sort function:

sort.cpp:33:5: error: no matching function for call to 'sort'
    std::sort(myvector[0], myvector.end()); 

What can be wrong?

    
asked by anonymous 22.12.2016 / 14:20

3 answers

6

Answering the question:

  

The problem you are having is in the sort function call:

The function sort is of type Comparable and should return a value of type bool (not a pointer to the CartesianPoint class).

There are still other problems in the program, such as the array of references, which can be changed by an array of pointers.

Here is a functional version with few modifications:

class CartesianPoint {
private:
    int x; // Coordinate X of a pin or a wire part on a cartesian plan
    int y; // Coordinate Y of a pin or a wire part on a cartesian plan

public:
    CartesianPoint() {}

    CartesianPoint(const CartesianPoint& orig)
    {}

    CartesianPoint(int x, int y) : x(x), y(y)
    {
    }

    virtual ~CartesianPoint()
    {}

    int getX() const {
        return x;
    }

    int getY() const {
        return y;
    }

};

// Aqui => a função retorna um boolean
bool myfunction(CartesianPoint *a, CartesianPoint *b) {
    return a->getX() < b->getX();
}

int main()
{
    int i;
    CartesianPoint *a = new CartesianPoint(10, 13), 
        *b = new CartesianPoint(32, 1), 
        *c = new CartesianPoint(5, 29), 
        *d = new CartesianPoint(12, 6), 
        *e = new CartesianPoint(21, 100);

    // Aqui => trocado para ponteiros e não referências!!
    CartesianPoint *myPoints[] = { a, b, c, d, e };

    // O vetor é de ponteiros!
    std::vector<CartesianPoint *> myvector(myPoints, myPoints + sizeof(myPoints) / sizeof(myPoints[0]));

    // using function as comp
    // O primeiro parâmetro é um iterator => begin()
    std::sort(myvector.begin(), myvector.end(), myfunction);

    // print out content:
    std::cout << "myvector contains:";
    for (i = 0; i < 5; i++)
        std::cout << ' ' << '(' << myvector[i]->getX() << ',' << myvector[i]->getY() << ')';
    std::cout << '\n';

    return 0;
}
    
22.12.2016 / 15:07
5

Well, given a low-key search here, I saw that there were several of these problems and their answers right here in the OS, the most complete I found here:

  

link

The problem is very simple. The function you chose to use is this:

void sort( RandomIt first, RandomIt last, Compare comp );

However, these variables first and last expect Iterators to scroll through your collection, since this function is implemented as a template to accept several types of collections. Your last is right, but first is wrong, you did not pass the iterator but the element. Please correct and enter the following:

std::sort(myvector.begin(), myvector.end(), myfunction); 

This is in the documentation itself: link

And also, its myfunction function returns a pointer to its object, and has to return a value of type bool , because it is a comparison function. You should also fix:

bool myfunction(CartesianPoint &a, CartesianPoint &b)
{
   return a.getX() < b.getX();
}
    
22.12.2016 / 14:57
3

It seems like converting a program from C # to C ++ ...

Below is a corrected C ++ 11 version, removing the C # isms:

#include <vector>
using std::vector;

#include <algorithm>
using std::sort;

#include <iostream>
using std::cout;

class CartesianPoint
{
   private:
      int x;
      int y;

   public:
      int getX() const { return x; }
      int getY() const { return y; }
      CartesianPoint(int x, int y) : x(x), y(y) { }
};

static bool myfunction(const CartesianPoint& a, const CartesianPoint& b)
{
   return a.getX() < b.getX();
}

int main() 
{
   vector<CartesianPoint> myvector { {10, 13}, {32, 1}, {5, 29}, {12, 6}, {21, 100} };

   sort(myvector.begin(), myvector.end(), myfunction); 

   cout << "myvector contains:";

   for (const auto& point : myvector)
       cout << ' ' << '(' << point.getX() << ',' << point.getY() << ')';

   cout << '\n';
}

ideone.com: link

Below a version for C ++ 14:

#include <vector>
using std::vector;

#include <algorithm>
using std::sort;

#include <iostream>
using std::cout;

class CartesianPoint
{
   private:
      int x;
      int y;

   public:
      int getX() const { return x; }
      int getY() const { return y; }
      CartesianPoint(int x, int y) : x(x), y(y) { }
      bool operator< (const CartesianPoint& that) const { return x < that.x; }

};

int main() 
{
   vector<CartesianPoint> myvector { {10, 13}, {32, 1}, {5, 29}, {12, 6}, {21, 100} };

   auto cmpFunc = [](const auto& p1, const auto& p2) { return p1 < p2; };
   sort(myvector.begin(), myvector.end(), cmpFunc); 

   cout << "myvector contains:";

   for (const auto& point : myvector)
       cout << ' ' << '(' << point.getX() << ',' << point.getY() << ')';

   cout << '\n';
}

ideone.com: link

That's it.

    
22.12.2016 / 14:57