# mem_fn.hpp
1.02.0001 (2001-08-30)

## Files

- mem_fn.hpp (implementation)
- mem_fn_test.cpp (test)

## 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.

## 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.

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.