apluscs
apluscs

Reputation: 85

struct comparator constructor vs operator () in c++

I have this code:

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));

I'm just confused on the explicit keyword. When I do a normal sort, I would call something like sort(sort(points.begin(), points.end(), compar()), and compar() points to the bool operator()(const Point& a, const Point& b) function, but now PointComparator(lowestPoint) refers to the constructor so how does it still work?

Upvotes: 0

Views: 1071

Answers (2)

eerorika
eerorika

Reputation: 238311

When I do a normal sort, I would call something like sort(sort(points.begin(), points.end(), compar()), and compar() points to the bool operator()(const Point& a, const Point& b) function

No it doesn't. compar() is syntax for a temporary object that is value initialised.

but now PointComparator(lowestPoint) refers to the constructor so how does it still work?

The arguments that you pass into the constructor affect which constructor is called. In the compar() case, the default constructor is used, and in the PointComparator(lowestPoint), the converting constructor is used. It works because PointComparator has a converting constructor of appropriate type.

I'm just confused on the explicit keyword.

It means that the constructor cannot be used in an implicit conversion. It prevents following from working: std::sort(b, e, lowestPoint);. Avoiding implicit converting constructors is often recommended.

Upvotes: 1

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122268

When I do a normal sort, I would call something like sort(sort(points.begin(), points.end(), compar()), and compar() points to the bool operator()(const Point& a, const Point& b) function, [...]

Actually, no. The third parameter passed to sort is a comparator. It can be a function object that has a operator(). You do not pass its operator() to the algorithm.

When you write:

std::sort(points.begin(), points.end(), PointComparator(lowestPoint));

this is more or less the same as

PointComparator compare(lowestPoint);
std::sort(points.begin(), points.end(), compare);

PointComparator(lowestPoint) is calling the constructor. The created object is passed to sort and only internally sort calls the operator().

The explicit here only means that implicit conversions from Point to PointComparator are blocked. It does not really have an effect on your code.

Upvotes: 2

Related Questions