4

Recently I noticed that C++ std::less is a class,although it simply compares the values of two objects.Here is a sample code:

template <class T> struct less {
  bool operator() (const T& x, const T& y) const {return x<y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

so what is the advantage of defining a class instead of a funciton? and I also wonder why using the 'const' keyword despite there is no data member in the class?

li yixiao
  • 59
  • 4
  • It's hard to give an answer _in general_. In this case, it's likely for consistency with other functors in the standard library. In general it's so "normal functions" can hold state (like classes and structs). As for "why const" --- because it's a good practice to mark everything as `const` as possible. – erip Dec 01 '21 at 12:49
  • related/dupe: https://stackoverflow.com/questions/37635300/function-pointer-vs-functors-in-c – NathanOliver Dec 01 '21 at 12:56
  • `typedef T first_argument_type; typedef T second_argument_type;` -- that's old, modern C++ does not have it – Alex Guteniev Dec 01 '21 at 12:59
  • 1
    In general, a functor (function object) can carry state, and additional information of use to the function it is passed to (e.g. typedefs), and a pointer to a function cannot. One specific advantage of passing (templated) functors by value as template argument is that the compiler has the opportunity to do inlining, which is often not feasible with function pointers - and that (assuming a modern optimising compiler) often gives a run-time performance advantage. – Peter Dec 01 '21 at 13:04
  • 1
    Does this answer your question? [why is std::less a functor?](https://stackoverflow.com/questions/18700731/why-is-stdless-a-functor) – Alex Guteniev Dec 01 '21 at 13:13

1 Answers1

5

Primarily to use it as a template parameter, like std::set<int, std::less<int>>.

Class template parameter in interfaces like std::set is used instead of pointer to function to be able to pass other function-like objects that do have some data members. In addition, making it a template parameter aids compiler optimizations, although modern compilers can optimize away function pointers in certain cases either.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • In addition `std::less*void*/>` (which allows *transparent* comparison) wouldn't match with pointer of function (it would be a full overload set). – Jarod42 Dec 01 '21 at 13:09
  • @Jarod42: That is true, but not the rationale for the original choice - the specialization wasn't in C++98. – MSalters Dec 01 '21 at 13:16