Boost logo

Boost Users :

From: David Morrison (dave_at_[hidden])
Date: 2005-03-23 04:20:12


Peter Dimov wrote:
> On a reasonably conforming compiler, adding an overload to apply<>
> should work:
>
> template<class F, class A1, class A2, class A3>
> result_type operator()
> (F & f, A1 & a1, A2 & a2, A3 & a3) const
> {
> return f(a1, a2, a3);
> }
>
> // add this
>
> template<class M, class T, class A1, class A2, class A3>
> result_type operator()
> (M T::* pm, A1 & a1, A2 & a2, A3 & a3) const
> {
> return mem_fn(pm)(a1, a2, a3);
> }
>
> It might be a good idea to add this to apply.hpp, but I would need to
> write a test for apply<> first.

Sorry for the incomplete previous post. What I meant to say was ...

That looks very interesting. And if I augment my previous code with
your suggestion I get the result below. Except for the obvious (and
expected) difference of needing to pass an instance of the class in
question, the member function and non-member function uses of apply look
identical. Very nice.

Dave

#include <vector>
#include <iostream>
#include <iterator>
#include "boost/bind.hpp"

namespace boost
{

template<class R> struct apply
{
   typedef R result_type;

   template<class M, class T, class A1, class A2, class A3>
   result_type operator()
     (M T::* pm, A1 & a1, A2 & a2, A3 & a3) const
   {
     return mem_fn(pm)(a1, a2, a3);
   }

   template<class F, class A1, class A2, class A3>
   result_type operator()(F & f, A1 & a1, A2 & a2, A3 & a3) const
   {
     return boost::mem_fn(f)(a1, a2, a3);
   }

   template<class F, class A1, class A2>
   result_type operator()(F & f, A1 & a1, A2 & a2) const
   {
     return f(a1, a2);
   }

  };

} // namespace boost

using namespace std;
using namespace boost;

struct A {
float a(int m, float x) { return m * x;}
float b(int m, float x) { return m + x;}
float c(int m, float x) { return m - x;}
float d(int m, float x) { return m / x;}
};

float a2(int m, float x) { return m * x;}
float b2(int m, float x) { return m + x;}
float c2(int m, float x) { return m - x;}
float d2(int m, float x) { return m / x;}

typedef float (A::*pfn)(int, float);
typedef float (*pfn2)(int, float);

int
main()
{
   A a;
   int m = 2;
   float x = 3.0;

   vector<pfn> v;
   vector<pfn2> v2;

   vector<float> f;

   v.push_back(&A::a);
   v.push_back(&A::b);
   v.push_back(&A::c);
   v.push_back(&A::d);

   v2.push_back(&a2);
   v2.push_back(&b2);
   v2.push_back(&c2);
   v2.push_back(&d2);

   transform(v.begin(), v.end(), back_inserter(f),
            bind(apply<float>(), _1, a, m, x));

   transform(v2.begin(), v2.end(), back_inserter(f),
            bind(apply<float>(), _1, m, x));

   copy(f.begin(), f.end(), ostream_iterator<float>(cout, "\n"));
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net