$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-users]  [bind] Need Help - Function Composition
From: loadcom (loadcom_at_[hidden])
Date: 2008-12-18 08:54:52
Hello all,
I'm using boost::bind to get elegant code. Thank the author 
for the great lib. I'm posting because I ran accross a small 
problem with the following code.
My intention of the code is to find the element of a container
with the least abs value of a member (i_).
template <typename Arg, typename Result>
class less_by_func
    : public std::binary_function<Arg, Arg, bool>
{
    typedef boost::function<Result(Arg)> fn_t;
    typedef less_by_func<Arg, Result> self_t;
    fn_t func_;
    less_by_func() {}    // not open
public:
    less_by_func(const self_t& src) : func_(src.func_) {}
    explicit less_by_func(const fn_t& func) : func_(func) {}
    template <typename Arg, typename Result>
    explicit less_by_func(const less_by_func<Arg, Result>& src) : func_(src.func_) {}
   
    bool operator()(const Arg& lhs, const Arg& rhs) const
    { return func_(lhs) < func_(rhs); }
};
// 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);
}
struct A
{
    int i_;
    A() : i_(0) {}
    explicit A(int i) : i_(i) {}
    void set(int i) { i_ = i; }
    int get() const { return i_; }
};
    std::vector<A> a_list;
    a_list.push_back(A(10));
    a_list.push_back(A(222));
    a_list.push_back(A(-100));
    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 following code doesn't get compile neither:
    std::stable_sort(a_list.begin(), a_list.end(), 
        make_less_by_func(boost::bind(&A::i_, _1)));
I know a more verbose version like this will also work:
    int min_abs = std::min_element(a_list.begin(), a_list.end(), 
        boost::bind(std::less(), 
        boost::bind(std::ptr_fun(&std::abs), boost::bind(&A::i_, _1)),
        boost::bind(std::ptr_fun(&std::abs), boost::bind(&A::i_, _2)) )
        )->i_;
But I just want the code to be as elegant as possible. :-)
My environment is: boost_1_36_0 + VS2003sp1
Thanks for any hints.
with best regards
Max
-------------------------------------------------------------------
ÐÂÀ˿ռ䡪¡ªÓëÅóÓÑ¿ªÐÄ·ÖÏíÍøÂçÐÂÉú»î£¡(http://space.sina.com.cn/ )