Boost logo

Boost :

Subject: [boost] [functional] New functor adaptors
From: Tigran Hayrapetyan (tigran.human_at_[hidden])
Date: 2013-09-12 08:03:51


Hello,

Suppose we want to transform sequence of integers by doubling and adding 5
to each value (x = 2*x + 5 for all x in sequence). If using std::transform,
then we need a functor which will for given "x" return "2*x + 5". My
question is - is it possible to do it in C++98 style (without lambda
expressions), and without writing additional functor class?
As I understand, it's not. For doing that we need something like nesting
functors into each other. Here we have "std::bind2nd(
std::multiplies<int>(), 2 )" functor, and "std::bind2nd( std::plus<int>(),
5 )" functor, which must be nested to provide necessary functionality. I
suggest something like "unary_result_translator" functor adapter, which is
unary functor itself, and which will apply unary functor to result of
another unary functor. The implementation of "unary_result_translator" can
be something like this:

template< typename Fn1, typename FnTrans >
class unary_result_translator
{
public:
  typedef typename Fn1::argument_type argument_type;
  typedef typename FnTrans::result_type result_type;

  unary_result_translator( const Fn1& fn1, const FnTrans& fn_trans )
  : fn1_( fn1 ), fn_trans_( fn_trans ) {}

  result_type operator()( const argument_type& arg ) const
  {
  return fn_trans_( fn1_( arg ) );
  }

  const Fn1& fn1_;
  const FnTrans& fn_trans_;
};

So, we will create our needed functor which converts "x" to "2*x + 5" by
this:

make_unary_result_translator( std::bind2nd( std::multiplies<int>(), 2 ),
std::bind2nd( std::plus<int>(), 5 ) )

Of'course, unary_result_translator can be also used for more complex
functors construction. Recently I used it for case-insensitive comparision
of strings only with help of ::tolower.

Similarly, there can be "binary_result_translator" which is binary functor
itself, and which will apply unary functor to result of binary functor.

Can that functor adaptors be useful? Or may be there is another way to do
such things?

Thanks for reading!

Best Regards,
Tigran Hayrapetyan


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