Creating a functor creator

A

alan

Hello all, I'd like to know if there is a nice method of defining a
functor creator which accepts an N-ary function and returns a functor
based on that function.

For example I have a function:
template<class X, class Y, class Z>
X function(Y, Z);

Passing it to the functor creator will give a functor equivalent to:
template<class X, class Y, class Z>
cell<X> functor(cell<Y>&, cell<Z>&);

cell<X> is an already-defined class I created which defers computation
- basically cell<X> + cell<X> will return a cell<X> which, when its
get_value() member function is called, will return the sum of the
source cells.

So far this is how I would implement it (unchecked):
template<class R, class A1, class A2>
class encell2 {
typedef R funtype(A1, A2);
funtype* funptr;
public:
encell2<R, A1, A2> (funtype& f): funptr(&f) {}
cell<R> operator()(const cell<A1> a1, const cell<A2> a2) const {
return cell<R>(
/*helper class to perform unpacking of data for us*/
new cell_function2<R, A1, A2>(funptr, a1, a2)
);
}
}
template<class R, class A1, class A2>
class cell_function2: public cell_internal{
/*not exactly how its done but this is a reasonable
approximation*/
boost::shared_ptr< cell_body<A1> > a1_;
boost::shared_ptr< cell_body<A2> > a2_;
typedef R funtype(A1, A2);
funtype *funptr;
public:
cell_function2<R, A1, A2>(const funtype* f, const cell<A1>&a1,
const cell<A2>& a2)
: funtype(f), a1_(a1.value_), a2_(a2.value_){ }
/*virtual function inherited from cell_internal*/
R get_value(){
return funptr(a1_->get_value(), a2_->get_value());
}
}

However, the solution above requires that I also add the arity to the
name. And it won't work with other functors (though I'm sure that's
possible, after all that's what the various variants of bind do).

I really liked the syntax of boost::function, where you just declare
the function's type in the template. However I got dizzy while trying
to hack through its code.
 
B

Barry

alan said:
However, the solution above requires that I also add the arity to the
name. And it won't work with other functors (though I'm sure that's
possible, after all that's what the various variants of bind do).

I really liked the syntax of boost::function, where you just declare
the function's type in the template. However I got dizzy while trying
to hack through its code.

http://groups.google.com/group/comp.lang.c++.moderated/msg/c84c97e168e627c4

I'd like to recommend you the implementation from
Thiago R. Adams
But now I can't access this page
 
A

alan

http://groups.google.com/group/comp.lang.c++.moderated/msg/c84c97e168...

I'd like to recommend you the implementation from
Thiago R. Adams
But now I can't access this page
I can. Thanks.

In any case, it appears very similar to the code I'm seeing in the
boost::function library - there's a bunch of macros for creating the
variable number of arguments, and several inclusions of the same file
with different numbers, even the comma-macro thing. Although it does
seem easier to read than the boost::function code. Hmm. Is
preprocessor hackery really the best solution?

I suppose I'll need to copy that preprocessor framework as well.
 
A

alan

For example I have a function:
template<class X, class Y, class Z>
X function(Y, Z);
Passing it to the functor creator will give a functor equivalent to:
template<class X, class Y, class Z>
cell<X> functor(cell<Y>&, cell<Z>&);


I can. Thanks.

In any case, it appears very similar to the code I'm seeing in the
boost::function library - there's a bunch of macros for creating the
variable number of arguments, and several inclusions of the same file
with different numbers, even the comma-macro thing. Although it does
seem easier to read than the boost::function code. Hmm. Is
preprocessor hackery really the best solution?

I suppose I'll need to copy that preprocessor framework as well.

No wait a minute, there's something I completely and totally forgot.

What the functor creator should return should be a polymorphic
functor. That is, it should return something equivalent to:
template<class X, class Y, class Z>
cell<X> functor(cell<Y>, cell<Z>){...}

template<class X, class Y, class Z>
cell<X> functor(Y y, cell<Z> z) {return functor(cell<Y>(y), z);}

template<class X, class Y, class Z>
cell<X> functor(cell<Y> y, Z z) {return functor(y, cell<Z>(z));}

template<class X, class Y, class Z>
cell<X> functor(Y y, Z z) {return functor(cell<Y>(y), cell<Z>(z));}


Dang. I can just barely imagine how to do it similar to
boost::function, but I can't imagine how this is to be done... I'll
need 2^N expansions. Hmm hmm hmm. This will really exercise the
preprocessor...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top