c++boost.gif (8819 bytes)

mem_fn.hpp

 

Files

Purpose

boost::mem_fn is a generalization of the standard functions std::mem_fun and std::mem_fun_ref. It supports member function pointers with more than one argument, and the returned function object can take a pointer, a reference, or a smart pointer to an object instance as its first argument.

mem_fn takes one argument, a pointer to a member function, and returns a function object suitable for use with standard or user-defined algorithms:

struct X
{
    void f();
};

void g(std::vector<X> & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};

void h(std::vector<X *> const & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};

void k(std::vector<boost::shared_ptr<X> > const & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};

The returned function object takes the same arguments as the input member function plus a "flexible" first argument that represents the object instance.

When the function object is invoked with a first argument x that is neither a pointer nor a reference to the appropriate class (X in the example above), it uses get_pointer(x) to obtain a pointer from x. Library authors can "register" their smart pointer classes by supplying an appropriate get_pointer overload, allowing mem_fn to recognize and support them.

A get_pointer overload for boost::shared_ptr is supplied.

[Note: get_pointer is not restricted to return a pointer. Any object that can be used in a member function call expression (x->*pmf)(...) will work.]

[Note: the library uses an unqualified call to get_pointer. Therefore, it will find, through argument-dependent lookup, get_pointer overloads that are defined in the same namespace as the corresponding smart pointer class, in addition to any boost::get_pointer overloads.]

All function objects returned by mem_fn expose a result_type typedef that represents the return type of the member function.

Interface

Synopsis

namespace boost
{

template<class T> T * get_pointer(T * p);

template<class T> T * get_pointer(shared_ptr<T> const & p);

template<class R, class T> implementation-defined-1 mem_fn(R (T::*pmf) ());

template<class R, class T> implementation-defined-2 mem_fn(R (T::*pmf) () const);

template<class R, class T, class A1> implementation-defined-3 mem_fn(R (T::*pmf) (A1));

template<class R, class T, class A1> implementation-defined-4 mem_fn(R (T::*pmf) (A1) const);

template<class R, class T, class A1, class A2> implementation-defined-5 mem_fn(R (T::*pmf) (A1, A2));

template<class R, class T, class A1, class A2> implementation-defined-6 mem_fn(R (T::*pmf) (A1, A2) const);

// implementation defined number of additional overloads for more arguments

}

Common requirements

All implementation-defined-N types mentioned in the Synopsis are CopyConstructible and Assignable. Their copy constructors and assignment operators do not throw exceptions. implementation-defined-N::result_type is defined as the return type of the member function pointer passed as an argument to mem_fn (R in the Synopsis.)

get_pointer

template<class T> T * get_pointer(T * p)

Returns: p.

Throws: Nothing.

template<class T> T * get_pointer(shared_ptr<T> const & p)

Returns: p.get().

Throws: Nothing.

mem_fn

template<class R, class T> implementation-defined-1 mem_fn(R (T::*pmf) ())

Returns: a function object f such that the expression f(t) is equivalent to (t.*pmf)() when t is an l-value of type T, (get_pointer(t)->*pmf)() otherwise.

Throws: Nothing.

template<class R, class T> implementation-defined-2 mem_fn(R (T::*pmf) () const)

Returns: a function object f such that the expression f(t) is equivalent to (t.*pmf)() when t is of type T [const], (get_pointer(t)->*pmf)() otherwise.

Throws: Nothing.

template<class R, class T, class A1> implementation-defined-3 mem_fn(R (T::*pmf) (A1))

Returns: a function object f such that the expression f(t, a1) is equivalent to (t.*pmf)(a1) when t is an l-value of type T, (get_pointer(t)->*pmf)(a1) otherwise.

Throws: Nothing.

template<class R, class T, class A1> implementation-defined-4 mem_fn(R (T::*pmf) (A1) const)

Returns: a function object f such that the expression f(t, a1) is equivalent to (t.*pmf)(a1) when t is of type T [const], (get_pointer(t)->*pmf)(a1) otherwise.

Throws: Nothing.

template<class R, class T, class A1, class A2> implementation-defined-5 mem_fn(R (T::*pmf) (A1, A2))

Returns: a function object f such that the expression f(t, a1, a2) is equivalent to (t.*pmf)(a1, a2) when t is an l-value of type T, (get_pointer(t)->*pmf)(a1, a2) otherwise.

Throws: Nothing.

template<class R, class T, class A1, class A2> implementation-defined-6 mem_fn(R (T::*pmf) (A1, A2) const)

Returns: a function object f such that the expression f(t, a1, a2) is equivalent to (t.*pmf)(a1, a2) when t is of type T [const], (get_pointer(t)->*pmf)(a1, a2) otherwise.

Throws: Nothing.

Implementation

This implementation supports member functions with up to eight arguments. This is not an inherent limitation of the design, but an implementation detail.

__stdcall support

Some platforms allow several types of member functions that differ by their calling convention (the rules by which the function is invoked: how are arguments passed, how is the return value handled, and who cleans up the stack - if any.)

For example, Windows API functions and COM interface member functions use a calling convention known as __stdcall.

To use mem_fn with __stdcall member functions, #define the macro BOOST_MEM_FN_ENABLE_STDCALL before including, directly or indirectly, <boost/mem_fn.hpp>.

[Note: this is a non-portable extension. It is not part of the interface.]

[Note: Some compilers provide only minimal support for the __stdcall keyword.]

Acknowledgements

Rene Jager's initial suggestion of using traits classes to make mem_fn adapt to user-defined smart pointers inspired the get_pointer-based design.

Numerous improvements were suggested during the formal review period by Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was Darin Adler.

Steve Anichini pointed out that COM interfaces use __stdcall.

Dave Abrahams modified bind and mem_fn to support void returns on deficient compilers.




Copyright © 2001 by Peter Dimov and Multi Media Ltd. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.