[bind, tuple] Custom comparison of tuple elements

Assume we have a range of objects of type tuple<T1,T2> and a function object that compares two objects of type T1. How would a person sort this range using this function object and bind? I want something along the lines of: std::sort(first, last, boost::bind<bool>(comp, boost::bind(boost::get<0>, _1), boost::bind(boost::get<0>, _2))); but this isn't remotely close to compiling. I could create a custom function object, but I'd rather learn how to use bind properly. Thanks, Mark

Mark Ruzon wrote:
Assume we have a range of objects of type tuple<T1,T2> and a function object that compares two objects of type T1. How would a person sort this range using this function object and bind? I want something along the lines of:
std::sort(first, last, boost::bind<bool>(comp, boost::bind(boost::get<0>, _1), boost::bind(boost::get<0>, _2)));
but this isn't remotely close to compiling. I could create a custom function object, but I'd rather learn how to use bind properly.
A very inconvenient question. :-) In principle, when you want to use bind with a function template: template <typename T> int f( T const & x); you supply its template parameters when binding it: bind( f<int>, _1 ); When you have several overloads: template <typename T> int f(const type1<T>& x); template <typename T> int f(const type2<T>& x); you cast it to the correct type or use a function pointer: int (*pf)( const type2<int>& ) = &f; bind( pf, _1 ); Going by this logic: T1 const & (*get0)( tuple<T1, T2> const & ) = &boost::get<0>; std::sort(first, last, boost::bind<bool>(comp, boost::bind(get0, _1), boost::bind(get0, _2))); This doesn't work, though. get<0> doesn't take a tuple, it actually takes a cons<Head, Tail>, an implementation detail of tuple: T1 const & (*get0)( tuple<T1, T2>::inherited const & ) = &boost::get<0>; This works under VC 8, at least. It doesn't link under VC 7.1; the compiler doesn't instantiate the correct get<0>. In conclusion... boost::get<> and boost::bind don't mix well. It would be easier to just write a get0 function for your tuple type or even a function object for the comparison.

Hi Mark, On 1/11/07, Mark Ruzon <ruzon@cs.stanford.edu> wrote:
Assume we have a range of objects of type tuple<T1,T2> and a function object that compares two objects of type T1. How would a person sort this range using this function object and bind? I want something along the lines of:
std::sort(first, last, boost::bind<bool>(comp, boost::bind(boost::get<0>, _1), boost::bind(boost::get<0>, _2)));
as Peter pointed out using overloaded function templates are a pain. However, if you define this one little get function (not even a functor) you may use it with bind easily: template< int N, class Tup > inline typename boost::tuples::element<N,Tup>::type& get(Tup& t) { return boost::tuples::get<N>(t); } Then, inside some scope where you can access this and bind arguments to your custom comparison functor typedef boost::tuples::tuple<int,float> tup; std::vector< tup > a(5); namespace b = boost; std::sort( a.begin(), a.end(), b::bind( mycompare, b::bind(get<0,tup>, ::_1), b::bind(get<0,tup>, ::_2) ) ); Now that you want to play around with these "beauties" (bind, tuple, etc..), here <http://rafb.net/p/q8aeR482.html> is a piece of compiling (and working) code which you might find entertaining. It also uses Boost.Lambdato fill-up the tuple vector, print-it out and sort with an inline lambda expression in addition to boost::bind'ed externally crafted functor. hth - levent -- Server Levent Yilmaz Mechanical Engineering @ PITT
participants (3)
-
Mark Ruzon
-
Peter Dimov
-
Server Levent Yilmaz