BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlf_memfn

Detailed Description

Outline

Purpose

Provide member function pointer wrapper classes and utility.

Classes

See also
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");
}
Definition bdlf_memfn.h:279

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");
}
Definition bdlf_memfn.h:821

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;
};
Forward declaration required by List_NodeProctor.
Definition bslstl_list.h:1033

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;
}
static MemFn< PROTOTYPE > memFn(PROTOTYPE func)
Definition bdlf_memfn.h:1236

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));
}