AMDG loadcom wrote:
<snip>
// helper function template<typename F> less_by_func<typename F::argument_type, typename F::result_type> make_less_by_func(F func) { return less_by_func<typename F::argument_type, typename F::result_type>(func); }
<snip>
int min_abs = std::min_element(a_list.begin(), a_list.end(), min2max::make_less_by_func( boost::function<int(A)>( boost::bind<int>( std::ptr_fun(&std::abs<int>), boost::bind(&A::i_, _1) ) ) ) )->i_; std::cout << min_abs << std::endl;
This code works fine, what I don't understand is why I couldn't remove the explicit construction of a boost::function<int(A)> object and let compiler do the implicit conversion(construction) silently. That means the following code doesn't work:
int min_abs = std::min_element(a_list.begin(), a_list.end(), min2max::make_less_by_func( boost::bind<int>( std::ptr_fun(&std::abs<int>), boost::bind(&A::i_, _1) ) ) )->i_;
The function objects created by Boost.Bind are plolymorphic. Thus, since they can be called with multiple different argument types, there is no way for them to provide an argument_type typedef. This means that in template<typename F> less_by_func<typename F::argument_type, typename F::result_type> make_less_by_func(F func); F is deduced as the result of the bind call, and SFINAE prevents this template from matching. The following definition of less_by_func should work better (untested) template<class F> struct less_by_func { typedef bool result_type; F f; template<class T> bool operator()(const T& t1, const T& t2) { return(f(t1) < f(t2)); } }; template<class F> less_by_func<F> make_less_by_func(F f) { less_by_func<F> result = { f }; return(result); } In Christ, Steven Watanabe