|
Boost Users : |
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/ )
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net