
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")); }