Functor Operations: A Complete Implementation

Ru-Brd

To illustrate the overall effect achieved by our sophisticated treatment of functor composition and value binding, we provide here a complete implementation of these operations for functors with up to three parameters. (It is straightforward to extend this to a dozen parameters or so, but we prefer to keep the printed code relatively concise .)

Let's first look at some sample client code:

  // functors/functorops.cpp  #include <iostream>  #include <string>  #include <typeinfo>  #include "functorops.hpp"  bool compare (std::string debugstr, double v1, float v2)  {      if (debugstr != "") {          std::cout << debugstr << ": " << v1                                        << (v1<v2? '<' : '>')                                        << v2 << '\n';      }      return v1<v2;  }  void print_name_value (std::string name, double value)  {      std::cout << name << ": " << value << '\n';  }  double sub (double a, double b)  {      return a-b;  }  double twice (double a)  {      return 2*a;  }  int main()  {      using std::cout;  // demonstrate composition:  cout << "Composition result: "           << compose(func_ptr(sub), func_ptr(twice))(3.0, 7.0)           << '\n';  // demonstrate binding:  cout << "Binding result: "           << bindfp<1>(compare, "main()->compare()")(1.02, 1.03)           << '\n';      cout << "Binding output: ";      bindfp<1>(print_name_value,                "the ultimate answer to life")(42);  // combine composition and binding:  cout << "Mixing composition and binding (bind<1>): "           << bind<1>(compose(func_ptr(sub),func_ptr(twice)),                      7.0)(3.0)           << '\n';      cout << "Mixing composition and binding (bind<2>): "           << bind<2>(compose(func_ptr(sub),func_ptr(twice)),                      7.0)(3.0)           << '\n';  } 

The program has the following output:

 Composition result: -8  Binding result:     main()->compare(): 1.02<1.03  1  Binding output:     the ultimate answer to life: 42  Mixing composition and binding (bind<1>): 8  Mixing composition and binding (bind<2>): -8 

The main conclusion that can be drawn from this little program is that using the functor operations developed in this section is very simple (even though implementing them was no easy task).

Note also how the binding and the composing templates interoperate seemlessly. The core facility that enables this is the small set of conventions we established for functors in Section 22.6.1 on page 436. This is not unlike the requirements established for iterators in the C++ standard library. Functors that do not follow our conventions are easily wrapped in adapter classes (as illustrated by our func_ptr() adaptation templates). Furthermore, our design allows state-of-the-art compilers to avoid any unnecessary run-time penalty compared to hand-coded functors.

Finally, the contents of functorops.hpp , which shows which header files are necessary to be able to compile the previous example, looks as follows :

  // functors/functorops.hpp  #ifndef FUNCTOROPS_HPP  #define FUNCTOROPS_HPP  // define  func_ptr()  ,  FunctionPtr  , and  FunctionPtrT  #include "funcptr.hpp"  // define  Composer<>  #include "compose6.hpp"  // define convenience function  compose()  #include "composeconv.hpp"  // define  Binder<>  // - includes  boundval.hpp  to define  BoundVal<>  and  StaticBoundVal<>  // - includes  forwardparam.hpp  to define  ForwardParamT<>  // - includes  functorparam.hpp  to define  FunctorParam<>  // - includes  binderparams.hpp  to define  BinderParams<>  // - includes  signselect.hpp  to define  SignSelectT<>  #include "binder5.hpp"  // define convenience functions  bind()  and  bindfp()  #include "bindconv.hpp"  #include "bindfp1.hpp"  #include "bindfp2.hpp"  #include "bindfp3.hpp"  #endif  // FUNCTOROPS_HPP  
Ru-Brd


C++ Templates
C++ Templates: The Complete Guide
ISBN: 0201734842
EAN: 2147483647
Year: 2002
Pages: 185

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net