Boost logo

Boost :

From: . Sneechy (sneechy_at_[hidden])
Date: 2002-08-08 19:47:05


Traits classes can make templates more generic and otherwise flexible
(performance-wise for example). I believe that the compose_f_*_t template
class family in boost/compose could benefit from using *ary_traits (from
boost/functional), and boost/call_traits.

Currently, compose_f_gx_t is defined like this:

  template <class OP1, class OP2>
  class compose_f_gx_t
   : public std::unary_function<typename OP2::argument_type,
                                typename OP1::result_type>
  {
    private:
      OP1 op1; // process: op1(op2(x))
      OP2 op2;
    public:
      // constructor
      compose_f_gx_t(const OP1& o1, const OP2& o2)
       : op1(o1), op2(o2) {
      }

      // function call

      typename OP1::result_type
      operator()(const typename OP2::argument_type& x) const {
          return op1(op2(x));
      }
  };

Using unary_traits for the operations would make this template directly
suitable for function pointers (among other benefits). Using call_traits in
the operator() parameter declaration would prevent reference-to-reference
type generation when OP2's argument type is a reference type, and would also
increase performance somewhat by having primitives passed by value.

The modified version of this particular compose class template would look
like this:

  template <typename OP1, typename OP2>
  class compose_f_gx_t
   : public std::unary_function<typename unary_traits<OP2>::argument_type,
                                typename unary_traits<OP1>::result_type>
  {
    private:
      typedef unary_traits<OP1> op1_traits;
      typedef unary_traits<OP2> op2_traits;

      op1_traits::function_type op1; // process: op1(op2(x))
      op2_traits::function_type op2;

    public:
      // constructor
      compose_f_gx_t(typename op1_traits::param_type o1,
                     typename op2_traits::param_type o2)
       : op1 (o1), op2 (o2) {
      }

      // function call
      typename op1_traits::result_type
      operator() (typename call_traits<typename
op2_traits::argument_type>::param_type x) const {
        return op1(op2(x));
      }
  };

These modifications would make the following code fragments valid:

  int a (int);
  int b (int);
  int c (int &);

  compose_f_gx(&a, &b); // error: int(*)(int) is not a class exposing
argument_type or result_type

  compose_f_gx(boost::ptr_fun(&a), boost::ptr_fun(&c)); // error:
reference-to-reference type generated

Several other Boost function object classes such as boost::binder2nd (from
boost/functional) already use these same techniques.

Do these modifications seem worthwhile to you guys?

Regards,

Eelis van der Weegen

_________________________________________________________________
MSN Photos is the easiest way to share and print your photos:
http://photos.msn.com/support/worldwide.aspx


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk