
Matthias Kaeppler <nospam@digitalraid.com> writes:
Thorsten Ottosen wrote:
Hi Matthias, "Matthias Kaeppler" <nospam@digitalraid.com> wrote in message news:d0ff4g$7rm$1@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