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:
-
- 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: 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 {
public:
void disconnect();
bool isAvailable() const;
};
class MyConnectionManager {
typedef bsl::list<MyConnection *> MyConnectionList;
MyConnectionList d_list;
public:
void disconnectAll();
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));
}