1 / 21

NKU CSC 601 Fall 2002 K. Kirby

Funcadelic. NKU CSC 601 Fall 2002 K. Kirby. Functionals & Function Objects for. Composition (the wrong way, the right way) C-function-pointer to function object adapter Binder (currying adaptor). f. g. Composition. (define compose (lambda (f g) (lambda (x) (f (g x)))))

leroy
Download Presentation

NKU CSC 601 Fall 2002 K. Kirby

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Funcadelic NKU CSC 601 Fall 2002 K. Kirby

  2. Functionals & Function Objects for... • Composition (the wrong way, the right way) • C-function-pointer to function object adapter • Binder (currying adaptor)

  3. f g Composition (define compose (lambda (f g) (lambda (x) (f (g x))))) ((compose sqrt to-real) "2") (map (compose abs sin) sequence)

  4. Composition double x= sqrt( atof( "2" ) ) ; // 1.414 double y= (compose( ptr_fun( sqrt ), ptr_fun( atof )))( "2" ) ; // 1.414

  5. Composition: Use with Algorithms double xar[N], yar[N] ; generate( xar, xar+N, rand ) ; // Compute |sin x| for every x in xar[]. transform( xar, xar+N, yar, compose( ptr_fun( fabs ), ptr_fun( sin ) ) ) ;

  6. Possibilities? ? unary_function<double,string> h= compose( ptr_fun( sqrt ), ptr_fun( atof )) ; ?? unary_function<double,string>* ph= & compose( ptr_fun( sqrt ), ptr_fun( atof )) ; ??? composition<double,double,string> h= compose( ptr_fun( sqrt ), ptr_fun( atof )) ; No no no.

  7. f g h An attempt: the functional template< typename TOut, typename TMid, typename TIn > unary_function<TOut,TIn> compose( unary_function<TOut,TMid> f, unary_function<TMid,TOut> g ) // // Create a composition (lambda x) (f(g(x)) // { Composition<TOut,TMid,TIn> h( f, g ) ; return h ; }

  8. f g An attempt: the functional template< typename TOut, typename TMid, typename TIn > unary_function<TOut,TIn> compose( unary_function<TOut,TMid> f, unary_function<TMid,TOut> g ) // // Create a composition (lambda x) (f(g(x)) // { return Composition<TOut,TMid,TIn>( f, g ) ; }

  9. g f An attempt: the function object template< typename TOut, typename TMid, typename TIn > class Composition : public unary_function< TIn, TOut > { public: Composition( const unary_function< TMid, TOut >& f, const unary_function< TIn, TMid >& g ) : _f(f) , _g(g) {} TOut operator()( TIn x ) { return _f( _g( x ) ) ; } private: unary_function< TMid, TOut > _f ; unary_function< TIn, TMid > _g ; } ; NO

  10. f g The right way: the functional template< typename UnFun1, typename UnFun2 > Composition<UnFun1,UnFun2> compose( const UnFun1& f, const UnFun2& g ) // // Create a composition (lambda x) (f(g(x))) // { return Composition<UnFun1,UnFun2>( f, g ) ; }

  11. g f The right way: the function object template< typename UnFun1, typename UnFun2 > class Composition : public unary_function< typename UnFun2::argument_type, typename UnFun1::result_type > { public: Composition( const UnFun1& f, const UnFun2& g ) : _f(f) , _g(g) {} typename UnFun1::result_type operator()( typename UnFun2::argument_type x ) { return _f( _g ( x ) ) ; } private: UnFun1 _f ; UnFun2 _g ; } ;

  12. C-function-pointer to function object adapter

  13. f Adapters: a functional template <typename TArg,typename TArg2, typename TArg3, typename TRes> TerFunAdapter<TArg,TArg2,TArg3,TRes> ptr_fun( TRes (*f)(TArg,TArg2,TArg3) ) // // A functor that takes a 3-arg function and returns the corresponding // ternary function object. // { return TerFunAdapter<TArg,TArg2,TArg3,TRes>( f ) ; }

  14. f Adapters: a function object template <typename TArg1, typename TArg2, typename TArg3, typename TRes> class TerFunAdapter: public ternary_function< TArg1, TArg2, TArg3, TRes > { public: TerFunAdapter( TRes (*f)(TArg1,TArg2,TArg3) ) // Constructor stores the function for later invocation. : _f(f) { } TRes operator()( const TArg1& arg1, const TArg2& arg2, const TArg3& arg3 ) const // Relays a call on this function object to a call on the underlying function. { return _f( arg1, arg2, arg3 ) ; } private: TRes (*_f( TArg1,TArg2,TArg3 ) ; } ;

  15. Binder (currying adaptor)

  16. Currying adapters (binders): a functional template <class TerFn, typename T> binder3rd<TerFn> bind3rd( const TerFn& f, const T& arg3 ) // Constructs and returns a Binder3rd object from this ternary function object and argument. { return binder3rd< TerFn >( f, arg3 ) ; } f arg3

  17. _f Binders: a function object _arg3 template <class TerFn> class binder3rd : public binary_function< typename TerFn::first_argument_type, typename TerFn::second_argument_type, typename TerFn::result_type > { public: binder3rd( const TerFn& f, const typename TerFn::third_argument_type arg3 ) // Constructs this binary function object by storing a ternary function object and the frozen 3rd arg. : _f(f), _arg3( arg3 ) { } typename TerFn::result_type operator() ( const typename TerFn::first_argument_type& arg1, const typename TerFn::second_argument_type& arg2 ) const // Translates the binary call to the ternary call with the stored 3rd argument. { return _f( arg1, arg2, _arg3 ) ; } private: TerFn _f ; // the underlying ternary function object typename TerFn::third_argument_type _arg3 ; // the frozen third argument } ;

  18. A little ternary function object template <typename TNum> struct SumIs : public ternary_function<TNum,TNum,TNum,bool> { bool operator()( const TNum& n1, const TNum& n2, const TNum& sum ) const { return n1 + n2 == sum ; } } ;

  19. Count the number of corresponding terms in these two sequences (*first1,...) (*first2,...) that satisfy the binary predicate pred2. // 20th Century Style template <typename Iter1, typename Iter2, typename Pred2> int count_match_if( Iter1 first1, Iter1 last1, Iter2 first2, Pred2 pred2 ) { int count= 0 ; while ( first1 != last1 ) if ( pred2( *first1++, *first2++ ) ) count++ ; return count ; } // 21st Century Style?? template <typename Iter1, typename Iter2, typename Pred2> int count_match_if( Iter1 first1, Iter1 last1, Iter2 first2, Pred2 pred2 ) { return inner_product( first1, last1, first2, 0, plus<int>(), pred2 ) ; }

  20. Count the number of positions in a pair of sequences where the corresponding elements to not add up to n. count_match_if( ls.begin(), ls.end(), ar, not2( bind3rd( SumIs<int>(), n ) ) ) ;

  21. struct Point { Point( double x =0, double y =0) : x(x), y(y) {} ; void translate( double dx, double dy ) { x += dx ; y += dy ; } void scale( double factor ) { x*= factor ; y*= factor ; } double getMagnitude() const { return sqrt( x*x + y*y ) ; } void print() const { cout << "(" << x << "," << y << ") " ; } ; double x, y ; } ; vector<Point> vpts(n) ; // ... for_each( vpts.begin(), vpts.end(), mem_fun_ref( Point::print ) ) ;

More Related