Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlf_memfn
[Package bdlf]

Provide member function pointer wrapper classes and utility. More...

Namespaces

namespace  bdlf

Detailed Description

Outline
Purpose:
Provide member function pointer wrapper classes and utility.
Classes:
bdlf::MemFn member function wrapper
bdlf::MemFnInstance member function wrapper with embedded instance pointer
bdlf::MemFnUtil utility for constructing wrapper objects
See also:
Component bdlf_bind
Description:
This component provides a member function pointer wrapper that wraps a member function pointer such that it can be invoked in syntactically the same manner as a free function. Two wrappers, each supporting member function pointers that accept from zero to fourteen arguments, are provided, as well as a utility to create such wrappers. Member function wrappers are commonly used as function objects for standard algorithms.
The first wrapper, bdlf::MemFn, contains a member function pointer and must be invoked with the first argument being a pointer or reference to the instance on which the function should be invoked, with the remaining arguments passed as arguments to the member function; that is, a wrapper memFn containing a pointer to a given memberFunction can be invoked as memFn(&object, args...) as opposed to object.memberFunction(args...).
The second wrapper, bdlf::MemFnInstance, contains both the member function pointer and a pointer to an instance of the type which contains the member, and is invoked with arguments which are passed as arguments to the member function; that is, a wrapper memFnInstance containing pointers to both a given memberFunction and to an object instance can be invoked as memFnInstance(args...) as opposed to object.memberFunction(args...).
Finally, the bdlf::MemFnUtil utility class provides utility functions for constructing bdlf::MemFn and bdlf::MemFnInstance objects.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Usage:
To illustrate basic usage more concretely, let us introduce a generic type:
  class MyObject {
    public:
      void doSomething(int, const char *);
  };
The following function invokes the member function doSomething on the specified objectPtr, with the two arguments 100 and "Hello", in two different ways. In both cases, object is passed as parameter to a function, and a wrapper is built containing a pointer to the doSomething member function. In the bdlf::MemFn case, the wrapper can be built once, so we make it a static local variable:
  void doSomethingWithMemFn(MyObject *objectPtr)
  {
      typedef bdlf::MemFn<void (MyObject::*)(int, const char *)> MemFnType;
      static MemFnType func(&MyObject::doSomething);

      func(objectPtr, 100, "Hello");
  }
In the bdlf::MemFnInstance case, the wrapper needs to contain the object as well, so it must be created at every function call:
  void doSomethingWithMemFnInstance(MyObject *objectPtr)
  {
      typedef bdlf::MemFnInstance<void (MyObject::*)(int, const char*),
                                 MyObject*> MemFnInstanceType;
      MemFnInstanceType func(&MyObject::doSomething, objectPtr);
      func(100, "Hello");
  }
This latter example is for exposition only. It would be much easier to invoke the member function directly. Note that both function calls ultimately result in the member function call:
  objectPtr->doSomething(100, "Hello");
Example 2: Usage with Standard Algorithms:
The following example demonstrates the use of bdlf::MemFn with the standard algorithms find_if and for_each. First we declare the MyConnection and MyConnectionManager classes used in the example, keeping the class definitions short to highlight the member functions for which we will later build wrappers:
  class MyConnection {

      // DATA (not shown)

    public:
      // CREATORS (not shown)

      // MANIPULATORS
      void disconnect();

      // ACCESSORS
      bool isAvailable() const;
  };

  class MyConnectionManager {

      // PRIVATE TYPES
      typedef bsl::list<MyConnection *> MyConnectionList;

      // DATA
      MyConnectionList d_list;

    public:
      // CREATORS (not shown)

      // MANIPULATORS
      void disconnectAll();

      // ACCESSORS
      MyConnection *nextAvailable() const;
  };
The nextAvailable function returns the next MyConnection object that is available. The find_if algorithm is used to search the list for the first MyConnection object that is available. find_if invokes the provided function object for each item in the list until a true result is returned, or the end of the list is reached. A bdlf::MemFn object bound to the MyConnection::isAvailable member function is used as the test functor. Note that the type of this object is never spelled out, it is built on the fly using the bdlf::MemFnUtil utility before being passed as a functor to the bsl::find_if algorithm:
  MyConnection *MyConnectionManager::nextAvailable() const
  {
      MyConnectionList::const_iterator it =
          bsl::find_if(d_list.begin(),
                       d_list.end(),
                       bdlf::MemFnUtil::memFn(&MyConnection::isAvailable));
      return it == d_list.end() ? 0 : *it;
  }
The disconnectAll function calls disconnect on each MyConnection object in the list. The for_each algorithm is used to iterate through each MyConnection object in the list and invoke the disconnect method:
  void MyConnectionManager::disconnectAll()
  {
      bsl::for_each(d_list.begin(),
                    d_list.end(),
                    bdlf::MemFnUtil::memFn(&MyConnection::disconnect));
  }