    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Flexible Functors and Binders</title>
        <link>https://members.accu.org/index.php/articles/436</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #44 - Aug 2001</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c160/">44</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-160/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+160/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Flexible Functors and Binders</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 August 2001 17:46:07 +01:00 or Sun, 26 August 2001 17:46:07 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>Functors and Binders are the key elements of Functional
Programming, a style of programming supported by the Standard C++
Library. Many of the Standard Library algorithms accept functors as
arguments, and there are several functors provided in the Standard
Library. However, binder support is limited to support for unary
functors and binary functors. Also, the type of the bound functor
is strongly tied to the type of the original, with no support for
default arguments, or arguments to be passed other than by const
reference. In this article I will describe an alternative set of
binders and functor wrappers that are more flexible in the way they
are called.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e22" id="d0e22"></a>The Standard
Library Facilities</h2>
</div>
<p>An article on Functors and Binders wouldn't be complete without
a discussion of the Standard C++ Library support. The Standard
Library support consists of 4 main things:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Functor base classes - <tt class=
"classname">std::unary_function</tt> and <tt class=
"classname">std::binary_ function</tt> - which provide typedefs for
the return type and argument types of the functor.</p>
</li>
<li>
<p>Function adaptors, which create functors derived from <tt class=
"classname">std::unary_function</tt> or <tt class=
"classname">std::binary_ function</tt> from pointers-to-functions,
and pointers-to-member-functions - e.g. <tt class=
"classname">std::pointer_to_unary_function</tt> and <tt class=
"classname">std::mem_fun_ref_t</tt>.</p>
</li>
<li>
<p>A set of standard functors, e.g. <tt class=
"classname">std:plus</tt> and <tt class="classname">std::unary_
negate</tt>. There are also Predicates (functors with a return type
of bool), such as <tt class="classname">std::less</tt>.</p>
</li>
<li>
<p>Binders for binary functions, <tt class=
"classname">std::binder1st</tt> and <tt class=
"classname">std::binder2nd</tt>. These bind the first and second
parameters, respectively, of a binary function (which must provide
the same typedefs as <tt class="classname">std::binary_
function</tt>, even if it doesn't derive from it), to specified
values, yielding an unary function. The argument provided when
these functors are invoked is then passed as the unbound parameter
of the original binary function.</p>
</li>
</ul>
</div>
<p>In addition, there are helper functions which assist in the
creation of the adaptor template classes and binder template
classes, by enabling automatic template type deduction to provide
the type of the adapted function, or its arguments. Examples of
these helper functions are <tt class="function">std::ptr_fun</tt>,
<tt class="function">std::mem_fun</tt> and <tt class=
"function">std::bind1st</tt>.</p>
<p>There was an introduction to the usage of the Standard Library
facilties by Steve Love in Overload 43 [<a href=
"#Love">Love</a>].</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e92" id="d0e92"></a>A New Way</h2>
</div>
<p>The restrictions of the Standard Library support for functors
and Binders can be quite limiting - what if you have a function
that takes 3 parameters? What if you want the first and third
parameters binding to given values? The Standard Library cannot
help you here, so you need a new set of Functor and Binder
classes.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e97" id="d0e97"></a>Adapting Plain
Functions</h2>
</div>
<p>What do we need in order to wrap a plain function in a functor
class? At the simplest level, let's consider a function that takes
no arguments - we need to know its return type, and that is all.
What about a function that has all-default arguments? We still need
the return type, but we also need to know the full type, so we can
keep a pointer to it. A first stab at a functor wrapper that can
support both of these is:</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename FunctionType&gt; 
class FunctorAdaptor { 
public: 
  FunctorAdaptor(FunctionType fun_): fun(fun_) {} 
  ReturnType operator()() const { return fun(); } 
private: 
  FunctionType fun; 
};
</pre>
<p>This class will support any functor that can be called with no
arguments, provided we know its return type. The only problem is
creating an object - specifying the template parameters can be
messy. For this purpose, we provide some helper functions:</p>
<pre class="programlisting">
template&lt;typename ReturnType&gt; 
FunctorAdaptor&lt;ReturnType,ReturnType (*)()&gt; 
  adapt(ReturnType (*fun)()) { return fun; } 

template&lt;typename ReturnType,typename Arg1&gt; 
FunctorAdaptor&lt;ReturnType,ReturnType (*)(Arg1)&gt; 
  adapt(ReturnType (*fun)(Arg1)) { return fun; } 

template&lt;typename ReturnType,typename Arg1,typename Arg2&gt; 
FunctorAdaptor&lt;ReturnType,ReturnType (*)(Arg1,Arg2)&gt; 
  adapt(ReturnType (*fun)(Arg1,Arg2)) { return fun; }
 
template&lt;typename ReturnType,typename Arg1,typename Arg2,typename Arg3&gt; 
FunctorAdaptor&lt;ReturnType,ReturnType (*)(Arg1,Arg2,Arg3)&gt; 
  adapt(ReturnType (*fun)(Arg1,Arg2,Arg3)) {   return fun; } 

template&lt;typename FunctorType&gt; 
FunctorAdaptor&lt;FunctorType::return_type,FunctorType&gt; 
  adapt(FunctorType fun) { return fun; }
</pre>
<p>These adaptors then create <tt class="classname">Functor</tt>
instantiations for any plain functions with up to 3 arguments (or
more, by simple extension), or any functor type that provides a
<span class="type">return_type</span> as a member (possibly a
<tt class="literal">typedef</tt>). This then covers all plain
functions (up to the limit on the number of arguments we specify),
and all functors derived from <tt class=
"classname">std::unary_function</tt> or <tt class=
"classname">std::binary_function</tt> - this therefore covers all
the Standard Library functors. For completeness we add a <tt class=
"literal">typedef return_type</tt> to our <tt class=
"classname">Functor</tt> class, so they look just like any other
functor.</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename FunctionType&gt; 
class FunctorAdaptor { 
public: 
  typedef ReturnType return_type; 
// rest as before 
};
</pre>
<p>One thing to note is that our <tt class=
"methodname">operator()</tt> still works, even if <span class=
"type">return_ type</span> is void, on a standard conforming
compiler. Some major compilers currently available still have not
implemented this feature, and so a workaround is required. The
library code available to accompany this article shows one such
workaround.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e141" id="d0e141"></a>Function
Arguments</h2>
</div>
<p>Even though we can create FunctorAdaptors for functions and
functors taking arguments, we can currently only call them if they
can be called without arguments. This is obviously a bit of a
limitation, so we must extend it to cope with arguments. We will
start with one argument, as whatever method we choose should be
extensible to more than one.</p>
<p>What type should the argument be? Since this is a
general-purpose adaptor class, we don't have that information
available, as that is encoded in the <i class=
"parameter"><tt>FunctionType</tt></i> template parameter.
Thankfully, the compiler comes to our rescue again, this time with
its template function type deduction facilities - if we make our
overload of <tt class="methodname">operator()</tt> a template
function, then the compiler can deduce the type of the argument
from the type of the supplied parameter.</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename FunctionType&gt; 
class FunctorAdaptor { 
public: 
  template&lt;typename Arg1&gt; 
  ReturnType operator()(Arg1 a1) const { return fun(a1);   } 
// rest as before 
};
</pre>
<p>To support multiple arguments, we supply multiple overloads of
<tt class="methodname">operator()</tt>, with different numbers of
parameters; because <tt class="classname">FunctorAdaptor</tt> is a
template class, only those member functions that are actually
invoked are compiled, so it doesn't matter if the adapted function
can be called with three arguments unless you call the <tt class=
"classname">FunctorAdaptor</tt> with three arguments.</p>
<p>The problem with this is that the compiler will never deduce
<i class="parameter"><tt>Arg1</tt></i> to be a reference type, so
all parameters will be passed by value. Not only can this be
expensive in terms of time and resources, but it is not always
possible - the class may not have an accessible copy constructor.
This also means that the original object cannot be modified, so if
the required parameter is a non-<tt class="literal">const</tt>
reference, the code will fail silently, with the temporary copy
being modified instead. The first problem is fixed by passing the
parameters by <tt class="literal">const</tt> reference, and this
will at least cause compile errors when using a function that
requires a non-<tt class="literal">const</tt> reference. Obviously,
this is still not ideal - we need some way of passing non-const
references. Here we ask for cooperation from our users - if they
want a parameter passed by reference, say so - for which purpose we
define a holder template, with a helper function.</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename FunctionType&gt; 
class FunctorAdaptor { 
public: 
  template&lt;typename Arg1&gt; 
  ReturnType operator()(const Arg1&amp; a1) const { return fun(a1); } 
// rest as before 
}; 
template&lt;typename T&gt; 
class RefHolder { 
public: 
  RefHolder(T&amp; ref_): ref(ref_) {} 
  operator T&amp;() const { return ref; } 
private: 
  T&amp; ref; 
}; 
template&lt;typename T&gt; 
RefHolder&lt;T&gt; byRef(T&amp; ref) { return ref; }
</pre>
<p>Then we call our functors like:</p>
<pre class="programlisting">
SomeFunctor(someArg,byRef(someRefArg));
</pre>
<p>Unfortunately, we can't then use this with the Standard
algorithms, because they don't know to use <i class=
"parameter"><tt>byRef</tt></i> when a reference argument is wanted.
However, we can note that all the Standard Library algorithms
require unary or binary functors only, so we can define some more
helper classes and helper functions.</p>
<pre class="programlisting">
template&lt;typename Functor&gt; 
class UnaryFunctorArgByRef { 
public: 
  typedef typename Functor::return_type return_type; 
  UnaryFunctorArgByRef(Functor fun_): fun(fun_) {} 
  template&lt;typename Arg1&gt; 
  return_type operator()(Arg1&amp; a1) const { return fun(byRef(a1)); } 
private: 
  Functor fun; 
};
 
template&lt;typename Functor&gt; 
class BinaryFunctorArgByRefByVal { 
public: 
  typedef typename Functor::return_type return_type; 
  BinaryFunctorArgByRef(Functor fun_): fun(fun_) {} 
  template&lt;typename Arg1,typename Arg2&gt; 
  return_type operator()(Arg1&amp; a1,const Arg2&amp; a2) const { return fun(byRef(a1),a2); } 
private: 
  Functor fun; 
};
 
template&lt;typename Functor&gt; 
UnaryFunctorArgByRef unaryByRef(Functor fun) { return fun; } 
template&lt;typename Functor&gt; 
BinaryFunctorArgByRefByVal binaryByRefByVal(Functor fun) { return fun; }
</pre>
<p>We also define <tt class="classname">binaryByValByRef</tt> and
<tt class="classname">binaryByRefByRef</tt> for completeness. It is
also relatively straightforward to define helpers for more
arguments if required, though the number of variations increases
exponentially.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e203" id="d0e203"></a>Member
Functions</h2>
</div>
<p>Sometimes it is desirable to use member functions as functors,
for example to call a member function on every object in a
container. These must then take at least one parameter, which will
provide an object on which to call the member function. The member
function itself can be stored using a pointer-to-member-function.
Since the syntax for calling a member function through a
pointer-to-member-function and an object is quite distinct from the
syntax for calling a normal function, we will need a new functor
class. At this point, we need to decide how we will be passing our
object - by pointer, or by reference. If we choose &quot;by pointer&quot;,
smart pointers can easily be used too, but it prohibits applying
member functions to objects held by value in containers. Therefore
we will take the Standard Library approach of providing both, with
the &quot;default&quot; (i.e. least typing) being &quot;by pointer&quot; - <tt class=
"function">adapt</tt> does &quot;by pointer&quot;, whereas <tt class=
"function">adaptObjByRef</tt> does &quot;by reference&quot;. Note also that
we need separate overloads of <tt class="function">adapt</tt> for
<tt class="literal">const</tt> and non-<tt class=
"literal">const</tt> member functions.</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename MemberFunctionType&gt; 
class MemberFunctorAdaptor { 
public: 
  typedef ReturnType return_type; 
  MemberFunctorAdaptor(MemberFunctionType fun_): fun(fun_) {}
  template&lt;typename ObjectPtrType&gt; 
  return_type operator()(ObjectPtrType objPtr) const { return ((*objPtr).*fun)(); } 
// we will deal with multiple arguments later 
private: 
  MemberFunctionType fun; 
}; 

template&lt;typename ReturnType,typename ObjectType&gt; 
MemberFunctorAdaptor&lt;ReturnType,ReturnType (ObjectType::*)()&gt; 
  adapt(ReturnType (ObjectType::*fun)()) { return fun; }
 
template&lt;typename ReturnType,typename ObjectType,typename Arg1&gt; 
MemberFunctorAdaptor&lt;ReturnType,ReturnType (ObjectType::*)(Arg1) const&gt; 
  adapt(ReturnType (ObjectType::*fun)(Arg1) const) { return fun; }
 
template&lt;typename ReturnType,typename ObjectType,typename MemberFunctionType&gt; 
class MemberFunctorAdaptorRef { 
public: 
  typedef ReturnType return_type; 
  MemberFunctorAdaptorRef(MemberFunctionType fun_): fun(fun_) {} 
  return_type operator()(ObjectType&amp; obj) const { return (obj.*fun)(); } 
private: 
  MemberFunctionType fun; 
};
 
template&lt;typename ReturnType,typename ObjectType&gt; 
MemberFunctorAdaptorRef&lt;ReturnType,ObjectType,ReturnType (ObjectType::*)()&gt; 
  adaptObjByRef(ReturnType (ObjectType::*fun)()) { return fun; } 

template&lt;typename ReturnType,typename ObjectType,typename Arg1&gt; 
MemberFunctorAdaptorRef&lt;ReturnType,const ObjectType, ReturnType(ObjectType::*)(Arg1)const&gt; 
  adaptObjByRef(ReturnType (ObjectType::*fun)(Arg1) const) { return fun; }
</pre>
<p>The helper functions can obviously be extended to support more
arguments. The functor returned from a call to <tt class=
"function">adapt</tt> can be called with any type as its first
argument, provided it supports <tt class=
"methodname">operator*</tt>, yielding a type on which it makes
sense to apply the given member function. Thus, for example, a
derived class pointer could be used if the member function was a
base class member, or a smart pointer such as <tt class=
"classname">std::auto_ptr</tt> could be used. On the other hand,
the functor returned from a call to <tt class=
"function">adaptObjByRef</tt> can only be called with objects that
support member functions of the appropriate type - i.e. objects of
the correct class, or a class derived from it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e239" id="d0e239"></a>Binders</h2>
</div>
<p>Now we can create functors from normal pointers-to-functions and
pointers-to-member-functions, and pass any type or number of
arguments to them. However, what if we want to, for example, write
every item in a container to <tt class="classname">std::cout</tt>,
given a function that takes two parameters - the object to write,
and the stream to write to? <tt class=
"classname">std::for_each</tt> only supports functors with one
argument and besides, we want to output to the same stream in each
case. To do this we use a <span class=
"emphasis"><em>Binder</em></span>, a functor that calls another
functor, fixing (binding) one of its arguments to a specified
value, and passing the others through unchanged. Our Binder class
needs to know three things - the functor it is to call, the object
to bind, and the argument number to bind it to. Since the argument
number changes the way the underlying functor is called, we will
define a separate class for each different number. This is the way
the Standard Library does it. That leaves a set of template
classes, each with two template parameters:</p>
<pre class="programlisting">
template&lt;typename FunctorType,typename BoundObjectType&gt; 
class Binder1st { 
public: 
  typedef typename FunctorType::return_type return_type; 
  Binder1st(FunctorType fun_,BoundObjectType obj_): fun(fun_),obj(obj_) {} 
  return_type operator()() const { return fun(obj); } 
  template&lt;typename Arg1&gt; 
  return_type operator()(const Arg1&amp; a1) const { return fun(obj,a1); } 
  // more overloads of operator() 
private: 
  FunctorType fun; 
  BoundObjectType obj; 
}; 

template&lt;typename FunctorType,typename BoundObjectType&gt; 
class Binder3rd { 
public: 
  typedef typename FunctorType::return_type return_type; 
  Binder3rd(FunctorType fun_,BoundObjectType obj_): fun(fun_),obj(obj_) {} 
  // must provide at least two arguments if bound value is to be the third 
  template&lt;typename Arg1,typename Arg2&gt; 
  return_type operator()(const Arg1&amp; a1,const Arg2&amp; a2) const {return fun(a1,a2,obj); }
  template&lt;typename Arg1,typename Arg2,typename Arg3&gt; 
  return_type operator()(const Arg1&amp; a1,const Arg2&amp; a2,const Arg3&amp; a3) const 
                  { return fun(a1,a2,obj,a3); } 
  // more overloads of operator() 
private: 
  FunctorType fun; 
  BoundObjectType obj; 
};
</pre>
<p>We then define some helper functions to deduce the template
parameters, which look like the following:</p>
<pre class="programlisting">
template&lt;typename FunctionType,typename BoundObjectType&gt; 
Binder1st&lt;FunctionType,const BoundObjectType&amp;&gt; 
  bind1st(FunctionType fun,const BoundObjectType&amp; obj) 
              { return Binder1st&lt;FunctionType,const BoundObjectType&amp;&gt;(fun,obj); }
</pre>
<p>Note that here we bind the fixed parameter by a <tt class=
"literal">const</tt> reference, since that is how it will be passed
to <tt class="methodname">operator()</tt> of our Functor classes.
This option permits us to bind non-<tt class="literal">const</tt>
references using <i class="parameter"><tt>byRef</tt></i> as before,
but <span class="emphasis"><em>only</em></span> if the bound
functor is being created as a temporary, since the <tt class=
"classname">RefHolder</tt> object will be destructed at the end of
the full expression. Therefore, if we want to keep the bound
Functor for later use, we will need to define another helper
function to keep a copy of the <tt class="classname">RefHolder</tt>
object in the bound Functor:</p>
<pre class="programlisting">
template&lt;typename FunctionType,typename BoundObjectType&gt; 
Binder1st&lt;FunctionType,RefHolder&lt;BoundObjectType&gt; &gt; 
  bind1stByRef(FunctionType fun,BoundObjectType&amp; obj) 
            { return Binder1st&lt;FunctionType,RefHolder&lt;BoundObjectType&gt; &gt;(fun,obj); }
</pre>
<p>Finally, it can be a bit messy to say <tt class=
"literal">bind1st(adapt(&amp;SomeClass::someMemberFunction),
someClassPtr)</tt>, so we define overloads of <tt class=
"classname">bind1st</tt> and <tt class=
"classname">bind1stByRef</tt> which automatically do the adapting
for plain functions or member functions as well, e.g.:</p>
<pre class="programlisting">
template&lt;typename ReturnType,typename ObjectType,typename Arg1,typename BoundObjectType&gt; 
Binder1st&lt;MemberFunctorAdaptor&lt;ReturnType,ReturnType (ObjectType::*)(Arg1)&gt;, 
      const BoundObjectType&amp;&gt; 
  bind1st(ReturnType (ObjectType::*fun)(Arg1),const BoundObjectType&amp; obj) { 
  return Binder1st&lt;MemberFunctorAdaptor&lt;ReturnType, ReturnType (ObjectType::*)(Arg1)&gt;, 
           const BoundObjectType&amp;&gt; (fun,obj); 
}
 
template&lt;typename ReturnType,typename Arg1,typename BoundObjectType&gt; 
Binder1st&lt;FunctorAdaptor&lt;ReturnType,ReturnType (*)(Arg1)&gt;, RefHolder&lt;BoundObjectType&gt; &gt; 
  bind1stByRef(ReturnType (*fun)(Arg1),BoundObjectType&amp; obj) { 
  return Binder1st&lt;FunctorAdaptor&lt;ReturnType, ReturnType (*)(Arg1)&gt;, 
           RefHolder&lt;BoundObjectType&gt; &gt;  (fun,obj); 
}
</pre>
<p>Now we have a solution to our original problem of printing the
contents of a container:</p>
<pre class="programlisting">
void write(const MyClass&amp;, std::ostream&amp;); 
std::for_each(container.begin(),container.end(), bind2nd(write,byRef(std::cout)));
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e301" id="d0e301"></a>Call Me
Later</h2>
</div>
<p>Looking at the variety of different types of functor, with all
their different template parameters, creating an object of the
correct type is not going to be easy. The user would have to
perform the same template type deductions as the compiler, and
explicitly specify all the template parameters. We want to avoid
this, as it is typing-intensive and error-prone, which is why we
provide the helper functions. This is fine for passing the functors
to Standard Library algorithms, as they are template functions and
thus the type of the functor is automatically deduced by the
compiler, but not for keeping the functor for later use.</p>
<p>Instead, what we can do is create a wrapper class, for which the
user specifies in a straightforward fashion what parameters and
return type they require. We then make this wrapper capable of
holding any of the miriad of functors, but only capable of calling
them as specified. The user can then pass round this wrapper.
Obviously, this is at the expense of a layer of indirection, and so
the resultant function call is slower. In this case, the
indirection takes the form of a virtual function call - we define a
template class derived from a non-template base class. The template
class can then be parameterized by the actual functor type without
affecting the containing class - we use a templated constructor of
our containing class to pick the right implementation class. We
pass all the arguments using <i class=
"parameter"><tt>byRef</tt></i> to ensure that the reference nature
is preserved. In order to ensure that the functor can be freely
copied with harm, the polymorphic implementation class is cloned
when the outer class is copied.</p>
<pre class="programlisting">
template&lt;typename ResultType,typename Arg1,typename Arg2,typename Arg3&gt; 
class Functor3 { 
private: 
  class FunctorImplBase { 
  public: 
    virtual ReturnType call(Arg1 a1,Arg2 a2,Arg3 a3) const=0; 
    virtual std::auto_ptr&lt;FunctorImplBase&gt; clone() const=0; 
    virtual FunctorImplBase() {} 
  }; 
  template&lt;typename FunctorType&gt; 
  class FunctorImpl:   public FunctorImplBase   { 
  public: 
    FunctorImpl(FunctorType fun_): fun(fun_) {} 
    virtual std::auto_ptr&lt;FunctorImplBase&gt; clone() const 
       { return std::auto_ptr&lt;FunctorImplBase&gt;(new FunctorImpl&lt;FunctorType&gt;(*this)); } 
    virtual ReturnType call(Arg1 a1,Arg2 a2,Arg3 a3) const 
       { return fun(byRef(a1),byRef(a2),byRef(a3)); } 
  private: 
    FunctorType fun; 
  }; 
public: 
  // make this Functor compatible with our binders 
  typedef ReturnType return_type; 
  // copy constructor - clone the contained Functor 
  Functor3(const Functor3&amp; old): funPtr(old.funPtr-&gt;clone()) {} 
  // template constructor 
  template&lt;typename FunctorType&gt; 
  Functor3(FunctorType fun): funPtr(new FunctorImpl&lt;FunctorType&gt;(fun)) {} 
  ReturnType operator()(Arg1 a1,Arg2 a2,Arg3 a3) const {return funPtr-&gt;call(a1,a2,a3); } 
private: 
  std::auto_ptr&lt;FunctorImplBase&gt; funPtr; 
};
</pre>
<p>We can then keep a copy of our functors for later use, like
so:</p>
<pre class="programlisting">
int someFunc(std::string&amp; a,double b); // our functor 
// bind a parameter and store it - note the argument and return types can differ from 
// the original, provided there is an implicit conversion 
std::string s(&quot;hello&quot;); 
Functor1&lt;float,int&gt; f(bind1stByRef(someFunc,s)); 
// now use it 
float a=f(19);
</pre>
<p>The resultant <tt class="classname">Functor1</tt> object can be
used with the standard library algorithms, or with the binders
described above, just like any other functor. It could also, for
example, be stored in a container along with other <tt class=
"classname">Functor1</tt> objects witht the same signature, even if
the underlying functor was completely different. Obviously, if an
argument is bound by reference, then the functor is useless if it
outlives the referred-to object.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e325" id=
"d0e325"></a>Conclusion</h2>
</div>
<p>I have introduced a new way of providing functor and Binder
support, which allows for variable numbers of arguments. This is
more flexible than the Standard Library facilities in that it
supports more than 2 arguments, and functors with variable number
of arguments (e.g. by having parameters with default values). It
also simplifies the syntax for binding e.g. member functions to
objects, and yet remains compatible with the Standard Library
algorithms.</p>
<p>The source code to accompany this article includes support for
functors taking up to 15 arguments, and is available from my
website.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e332" id="d0e332"></a>References and
Further Reading</h2>
</div>
<div class="bibliomixed"><a name="Love" id="Love"></a>
<p class="bibliomixed">[Love] Are You Afraid Of The Dark? - Making
Sense of the STL, Steve Love, <span class="citetitle"><i class=
"citetitle">Overload 43</i></span>.</p>
</div>
<div class="bibliomixed"><a name="Alexandrescu" id=
"Alexandrescu"></a>
<p class="bibliomixed">[Alexandrescu] <span class=
"citetitle"><i class="citetitle">Modern C++ Design</i></span>,
Andrei Alexandrescu. Chapter 5.</p>
</div>
<div class="bibliomixed"><a name="Williams" id="Williams"></a>
<p class="bibliomixed">[Williams] <span class="bibliomisc"><a href=
"http://cplusplus.anthonyw.cjb.net" target=
"_top">http://cplusplus.anthonyw.cjb.net</a></span> - my website,
with source code to accompany this article</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
