A function object or a Functor is an instance of a class that overloads the function-call operator '()'. Functors are generally used as callback functions. They have advantages over standard function pointers because, being objects, they can have properties and maintain state.

Let's look at a simple use case of Functor to filter the objects of a class Employee from a collection to another collection:

struct Employee { std::string name_; int salary_; std::string department_; //.. more members };

And, a collection of Employees:

/* Collection of Employees. We use C++11 list-initialization here. Fill the collection with multiple push_back calls if your compiler doesn't support list-initialization. */ std::vector<Employee> employees = { {"Sam", 50000, "sales"}, {"Mac", 70000, "marketing"}, {"Dot", 90000, "research"}, {"Ted", 60000, "sales"}, };

For the sake of simplicity, we are storing Employee objects directly within the STL collection. Note that, moving the elements within a collection (e.g. sorting) invokes copy/move operations (copy/move constructor or assignment operator). If the stored objects are big or frequent copy/move operations are expected, it could be better to store the pointers to objects in the collection.

We use STL algorithm std::copy_if to filter the sales department Employees from collection employees to another collection sales_employees. The last argument to std::copy_if is a predicate that can be a function pointer, a functor, or (since C++11) a lambda expression.

std::vector<Employee> sales_employees; /* std::copy_if(employees.begin(), employees.end(), std::back_inserter(sales_employees), predicate); */

A predicate is a function that would be called by std::copy_if for each Employee object in employees to decide if the object can be copied to sales_employees or not. A simple predicate can be a pointer to a global function, and can be used as follows:

bool is_sales_employee(const Employee& e) { return e.department_ == "sales"; } std::copy_if(employees.begin(), employees.end(), std::back_inserter(sales_employees), is_sales_employee);

As you can see that the global function - is_sales_employee - is not generic because it is for only sales department. We can do a better job by creating a functor class - IsDeptEmployee - and using its instances as predicates to filter employees of any department:

// A functor class for any department struct IsDeptEmployee { explicit IsDeptEmployee(const char* dept) :department_(dept){ } /* Overloaded operator () to create a functor */ bool operator () (const Employee& e) { return e.department_ == department_; } std::string department_; };

Now, we can use the instances of IsDeptEmployee like regular functions, e.g.:

IsDeptEmployee isResearchEmployee("research"); if( isResearchEmployee(employees[2]) ) // calling 'operator ()' std::cout << employees[2].name_;

And, this is how we can use IsDeptEmployee's instance to filter sales employees:

std::copy_if(employees.begin(), employees.end(), std::back_inserter(sales_employees), IsDeptEmployee("sales"));

Suppose we want to sort the employees collection by salaries of Employees in descending order. We are going to use another STL algorithm std::sort whose last argument - just like predicate in std::copy_if - is a comparator. The comparator could be a functor that takes two arguments for comparison and returns true if the first argument is less than the second:

struct SalaryComparator { // overloaded operator () }; std::sort(employees.begin(), employees.end(), SalaryComparator());

Select the correct definition of overloaded operator () in SalaryComparator for sorting in descending order (check Explanations for details):