2

I am trying to implement Graham scan, and I want to do something like this:

private static void sortByPolar(Point[] points, Point r) {
    Arrays.sort(points, (p, q) -> {
    int compPolar = ccw(p, r, q);
    int compDist = dist(p, r) - dist(q, r); 
    return compPolar == 0 ? compDist : compPolar;
});

where Point r is the bottommost point. However, I am struggling to implement this same idea in c++ because I can only pass in the function of compar and I don't know how that can access the lowest point.

struct compar {
  vector<vector<int>> lowest;
  bool operator()(vector<int> const& a, vector<int> const& b) {
    cout<<lowest[0]<<endl;    // throws an error, how do I get this function access to lowest?
    return // TODO;
  }
};

// in another function:
sort(points.begin(), points.end(), compar());
apluscs
  • 75
  • 5

1 Answers1

3

You can give compar a constructor, with a parameter for the data you want, then just pass it in as an argument when you create the temporary instance:

struct compar {
  explicit compar(vector<int> const& lowest) : m_lowest(lowest) {}
  
  bool operator()(vector<int> const& a, vector<int> const& b) {
    cout<<m_lowest[0]<<endl;
    return // TODO;
  }

private:
  vector<int> m_lowest;
};

// in another function:
vector<int> lowestPoint;  // (get this from somewhere)
sort(points.begin(), points.end(), compar(lowestPoint));

By the way, a whole vector just for two ints for every point seems pretty wasteful, and it's also not very descriptive. Why not make a nice Point type?

struct Point
{
   int x, y;
};

struct PointComparator
{
   explicit PointComparator(const Point& lowest)
      : m_lowest(lowest)
   {}
   
   bool operator()(const Point& a, const Point& b)
   {
      std::cout << m_lowest[0] << std::endl;
      return; // TODO
   }

private:
   Point m_lowest;
};

// in another function:
Point lowestPoint;  // (get this from somewhere)
std::sort(points.begin(), points.end(), PointComparator(lowestPoint));
Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • Thanks! Now l'm just confused on the explicit keyword. When l do a normal sort, l would call `sort(sort(points.begin(), points.end(), compar())`, and `compar()` points to the `bool operator()(const Point& a, const Point& b)` function, but now `compar(lowest)` refers to the constructor so how does it still work? – apluscs Jan 01 '21 at 01:56
  • @apluscs _"compar() points to the bool operator()(const Point& a, const Point& b) function"_ Nope! That was just creating a temporary with the default constructor. The `operator()` is done for you by the sort algorithm. It would look like `compare()(a, b)` (or, now, `compare(lowest)(a,b)`) if you did it yourself :) You can pre-declare it if it's clearer: `compar myCompar(lowest); sort(points.begin(), points.end(), myCompar);` – Asteroids With Wings Jan 01 '21 at 15:15
  • @apluscs _"Now l'm just confused on the explicit keyword."_ Just good practice when you have a single-argument constructor. – Asteroids With Wings Jan 01 '21 at 15:15