Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-03-07 09:55:43


Matthias Kaeppler <nospam_at_[hidden]> writes:

> Thorsten Ottosen wrote:
>> Hi Matthias,
>> "Matthias Kaeppler" <nospam_at_[hidden]> wrote in message
>> news:d0ff4g$7rm$1_at_sea.gmane.org...
>> | Hello,
>> |
>> | because of the lack of a generic adaptor which indirects operations on
>> | pointers to the pointees, i.e. sorting a collection of pointers with
>> | predicates applying to the pointees, I have come up with two classes,
>> | indirecter_unary and indirecter_binary which do exactly that (thanks
>> | again to the people from boost users and comp.lang.c++ for assisting
>> | me). Both adaptors accept adaptable function objects as well as plain
>> | functions.
>> these classes are useful when we need to use a class; boost.bind
>> won't
>> work since we don't know what type it returns.
>> I have been playing with similar functionality for Boost.Pointer
>> Container
>> because the ptr_set class needs it.
>> I have a question, though. I'm thinking, what is the benefit of your
>> approach compared to
>> template< class Fun >
>> class indirect_fun
>> {
>> Fun fun;
>> public:
>> typedef typename result_of<Fun>::type result;
>> indirect_fun( Fun f ) : fun(f)
>> { }
>> template< class T >
>> result operator( T* r ) const
>> { return fun( *r ); }
>> template< class T, class U >
>> result operator( T* r, U* r2 ) const
>> { return fun( *r, *r2 ); }
>> // etc
>> };

This is too specific for Matthias' purposes (doesn't work on
containers of iterators or smart pointers). Maybe something like:

template< class Fun >
struct indirect_fun
{
    indirect_fun( Fun f ) : fun(f)
    { }

    template< class T >
    typename
       result_of<Fun(typename pointee<T>::type)>::type
    operator()( T const& r ) const
    { return fun( *r ); }

    template< class T, class U >
    typename result_of<
        Fun(
            typename pointee<T>::type,
            typename pointee<U>::type,
        )>::type
    operator( T const& r, U const& r2 ) const
    { return fun( *r, *r2 ); }

    // etc
private:
    Fun fun;
};

>> br
>> -Thorsten _______________________________________________
>> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>>
>
> There are several problems with this template.
>
> First, it's not an "Adaptable Binary Function" or "Adaptable Unary
> Function", because it fails to provide the required typedefs result_type
> and argument_type, and result_type and first_argument_type,
> second_argument_type respectively.

IMO that's not very important. (Statically) polymorphic function
objects like the above are increasingly common, and your design
doesn't allow them to be adapted. For example:

  struct add
  {
      template <class T>
      T operator()(T x, T y) const { return x+y; }
  };

Now take a container of pointers to T and add the Ts up using
std::accumulate and add, above.

> Second, it might fail to compile when Fun takes arguments by
> reference.

??

Why would it fail?

> I had problems at this part, that's why I used the boost type traits
> library to remove any references on the type first, and only work on
> "raw" const-pointers.

> Third, (correct me if I'm wrong, I haven't used it before), as far as I
> understand, the result_of class template won't work if you instantiate
> your template with a plain function.

Accounted for above.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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