Function adaptors in c++

A function adaptors in c++ is an instance of a class that adapts a global or member function so that the function can be used as a function object. A function adaptor may also be used to alter the behavior of a function or function object. Each function adaptor provides a constructor that takes a global or member function. The adaptor also provides a parenthesis operator that forwards its call to that associated global or member function.

Adapting Global Functions

The pointer to unary function and to binary function templates adapt global functions of one or two arguments. These adaptors can be applied directly, or the ptr_fun of function template can be used to construct the appropriate adaptor automatically. For instance, a simple times_3 function can be adapted and applied to a vector of integers as follows:

int times3(int x) {
  return 3*x;
}

int a{} {1,2,3,4,5};
vector<int> v(a,a+5), v2;

transform(v.begin(),v.end(),v2.end(),ptr_fun(times3));

In Alternative, the adapter could have been applied, and the new, adapted function object passed to the vector:

pointer_to_unary_function<int,int> pf(times3);
transform(v.begin(),v.end(),v2.end(),pf);

This example points out the advantage of allowing the compiler to deduce the types needed by pointer to unary function through the use of ptr_fun.

Adapting Member Functions

The mem_fun family of templates adapts member functions, rather than global functions. For instance, to sort each list in a given a set of lists, mem_fun_t or simply mem_fun can be used to apply the list sort member function to each element in the set:

set<list<int>* > s;

// Initialize the set with lists

// Sort each list in the set.
for_each(s.begin(),s.end(),mem_fun(&list<int>::sort));

// Now each list in the set is sorted

Using mem_fun is necessary because the generic sort algorithm can’t be used on a list. It is also the simplest way to access any polymorphic characteristics of an object held in a standard container. For example, a virtual draw function might be invoked on a collection of objects that are all part of the canonical shape hierarchy like as given below:

// shape hierarchy
class shape {
   virtual void draw();
};

class circle : public shape {
   void draw();
};

class square : public shape {
  void draw();
};

//  Assemble a vector of shapes
circle c;
square s;
vector<shape*> v;
v.push_back(&s);
v.push_back(&c);

// Call draw on each one
for_each(v.begin(),v.end(), mem_fun(&shape::draw));

Like the global function adaptors, every member function adaptor consists of a class template and an associated function template. The class is the actual adaptor, while the function simplifies the use of the class by constructing instances of that class on the fly. For instance, in the above example, a user could construct a mem_fun_t, and pass that to the for_each algorithm:

mem_fun_t<shape> mf(&shape::draw);
for_each(v.begin(),v.end(),mf);

Here again the mem_fun function template simplifies the use of the mem_fun_t adaptor by allowing the compiler to deduce the type needed by mem_fun_t.

The Standard C++ Library provides member function adaptors for functions with zero arguments as above and also with one argument. They can be simply extended to member functions with more arguments.