Function Objects in C++

(Heavily from https://cplusplus.com/reference/functional/)

Function objects are objects that work as functions. On an implementation level, however, function objects are objects of a class that implement operator(), with zero to any number of arguments. Although functions and function-pointers can also be classified as function objects, it is the capability of an object of a class that implements operator() to carry state (that is, values in member attributes of the class) that makes it so useful.

Function objects that return a boolean type (predicates) naturally are used in algorithms that need decision-making.

They are typically used as arguments to functions, such as predicates or comparison functions passed to standard algorithms.

Function std::bind in Depth (<functional>)

Prototypes:

template <class Fn, class... Args>
bind (Fn&& fn, Args&&... args);
template <class Ret, class Fn, class... Args>
bind (Fn&& fn, Args&&... args);

bind() returns a function object based on fn, but with its arguments bound to args. Each argument may either be bound to a value or be a placeholder:

Calling the returned object returns the same type as fn, unless a specific return type is specified as Ret (second prototype). (Note that Ret is the only template parameter that cannot be implicitly deduced by the arguments passed to this function).


The type of the returned object has the following properties:

>An example:

[...]

// bind example
#include <iostream>     // std::cout
#include <functional>   // std::bind

// a function: (also works with function object: std::divides<double> my_divide;)
double my_divide (double x, double y) {return x/y;}

struct MyPair {
  double a,b;
  double multiply() {return a*b;}
};

int main () {
  using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

  // binding functions:
  auto fn_five = std::bind (my_divide,10,2);               // returns 10/2
  std::cout << fn_five() << '\n';                          // 5

  auto fn_half = std::bind (my_divide,_1,2);               // returns x/2
  std::cout << fn_half(10) << '\n';                        // 5

  auto fn_invert = std::bind (my_divide,_2,_1);            // returns y/x
  std::cout << fn_invert(10,2) << '\n';                    // 0.2

  auto fn_rounding = std::bind<int> (my_divide,_1,_2);     // returns int(x/y)
  std::cout << fn_rounding(10,3) << '\n';                  // 3

  MyPair ten_two {10,2};

  // binding members:
  auto bound_member_fn = std::bind (&MyPair::multiply,_1); // returns x.multiply()
  std::cout << bound_member_fn(ten_two) << '\n';           // 20
  auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a
  std::cout << bound_member_data() << '\n';                // 10

  return 0;
}

[...]

Functions std::ref and std::cref in Depth (<functional>)

...

Prototypes:

template <class T> reference_wrapper<T> ref (T& elem) noexcept;
template <class T> reference_wrapper<T> ref (reference_wrapper<T>& x) noexcept;
template <class T> void ref (const T&&) = delete;

template <class T>  reference_wrapper<const T> cref (const T& elem) noexcept;
template <class T>  reference_wrapper<const T> cref (reference_wrapper<T>& x) noexcept;
template <class T>  void cref (const T&&) = delete;

These functions return a reference_wrapper object of the appropriate type to hold an element of type T or const T respectively.

An example:

// ref example
#include <iostream>     // std::cout
#include <functional>   // std::ref

int main () {
  int foo (10);

  auto bar = std::ref(foo);

  ++bar;
  std::cout << foo << '\n';

  return 0;
}

(Note that should we have invoked std::cref instead, the returned object, bar, would not be incrementable, but the source object, foo, would.)

Function std::mem_fn (<functional>)

template <class Ret, class T>
/* unspecified */ mem_fn (Ret T::* pm);

std::mem_fn converts member function pm to a function object. It returns a function object whose functional call invokes the member function pointed by pm.


The type of the returned object has the following properties: