[lambda] Writing pass-through 'standard' algorithms

I encountered this difficulty in the context of passing lambda functors, but on reflection I don't the lambda aspect particularly matters. Consider this templated function template <typename InputIterator, typename Predicate> inline bool all_if( InputIterator first, InputIterator last, Predicate predicate ) { return std :: find_if( first, last, std :: not1( predicate ) ) == last; } Obviously the intent is to enquire if all members of a range satisfy the predicate. Now, as is, this doesn't compile, because it needs ptr_fun() on the predicate, but then a couple of things come up. - ptr_fun( ) requires that it's argument is a pointer-to-function - I'd like my all_if( ) to permit functions or functors, including lambda functors How can this be done? Is it impossible to dress-up a standard algorithm in this way? Thanks, Rob. -- ACCU - Professionalism in programming - http://www.accu.org

On Tue, Jul 22, 2008 at 12:01 AM, Robert Jones <robertgbjones@gmail.com> wrote: [snip]
Obviously the intent is to enquire if all members of a range satisfy the predicate.
Now, as is, this doesn't compile, because it needs ptr_fun() on the predicate, but then a couple of things come up.
- ptr_fun( ) requires that it's argument is a pointer-to-function - I'd like my all_if( ) to permit functions or functors, including lambda functors
How can this be done? Is it impossible to dress-up a standard algorithm in this way?
You can add an additional level of indirection which has different implementations in cases where: 1. You have a function object derived from std::unary_function. 2. You have a function pointer passed as an argument. 3. You have a lambda/bind expression. You'd have to do something like this: template <class InputIterator, class Predicate> inline bool all_if(InputIterator first, InputIterator last, Predicate predicate) { // defer implementation typedef dispatch_on<Predicate>::type predicate_tag; return all_if_impl(first, last, predicate, predicate_tag()); } template <class InputIterator, class Predicate> inline bool all_if_impl(InputIterator first, InputIterator last, Predicate predicate, unary_function_tag); template <class InputIterator, class Predicate> inline bool all_if_impl(InputIterator first, InputIterator last, Predicate predicate, lambda_expression_tag); ... HTH -- Dean Michael C. Berris Software Engineer, Friendster, Inc.

----- Original Message ----- From: "Robert Jones" <robertgbjones@gmail.com> To: <boost@lists.boost.org> Sent: Monday, July 21, 2008 6:01 PM Subject: [boost] [lambda] Writing pass-through 'standard' algorithms
I encountered this difficulty in the context of passing lambda functors, but on reflection I don't the lambda aspect particularly matters.
Consider this templated function
template <typename InputIterator, typename Predicate> inline bool all_if( InputIterator first, InputIterator last, Predicate predicate ) { return std :: find_if( first, last, std :: not1( predicate ) ) == last; }
Obviously the intent is to enquire if all members of a range satisfy the predicate.
Now, as is, this doesn't compile, because it needs ptr_fun() on the predicate, but then a couple of things come up.
What exactly do not compiles? I have not founf ptr_fun on your function. If predicate is a predicate functor this should compile, isn't it? The following compiles: template <typename InputIterator, typename Predicate> inline bool all_if( InputIterator first, InputIterator last, Predicate predicate ) { return std::find_if(first, last, std::not1( predicate ) ) == last; } struct IntGreaterThanThree : public std::unary_function<int, bool> { bool operator() (int x) const { return x > 3; } }; int main() { std::vector<int> L; L.push_back(5); L.push_back(8); L.push_back(4); L.push_back(10); std::cout << "=" << all_if (L.begin(), L.end(), IntGreaterThanThree()) << std::endl; return 0; } Vicente

On Mon, Jul 21, 2008 at 9:55 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What exactly do not compiles? I have not founf ptr_fun on your function. If predicate is a predicate functor this should compile, isn't it? The following compiles:
template <typename InputIterator, typename Predicate> inline bool all_if( InputIterator first, InputIterator last, Predicate predicate ) { return std::find_if(first, last, std::not1( predicate ) ) == last; } struct IntGreaterThanThree : public std::unary_function<int, bool> { bool operator() (int x) const { return x > 3; } };
int main() { std::vector<int> L; L.push_back(5); L.push_back(8); L.push_back(4); L.push_back(10); std::cout << "=" << all_if (L.begin(), L.end(), IntGreaterThanThree()) << std::endl; return 0; }
Sorry, I'm not explaining myself too well. Yes your example compiles, provided the predicate is an adaptable functor (typedefs argument_type). If the predicate is a raw function then the ptr_fun adaptor is required, but that will ONLY work for a raw pointer. My difficulty is in finding a direct solution that works for all cases. Regards, Rob.

----- Original Message ----- From: "Robert Jones" <robertgbjones@gmail.com> To: <boost@lists.boost.org> Sent: Monday, July 21, 2008 11:07 PM Subject: Re: [boost] [lambda] Writing pass-through 'standard' algorithms
On Mon, Jul 21, 2008 at 9:55 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
What exactly do not compiles? I have not founf ptr_fun on your function. If predicate is a predicate functor this should compile, isn't it? The following compiles:
<snip>
Sorry, I'm not explaining myself too well. Yes your example compiles, provided the predicate is an adaptable functor (typedefs argument_type). If the predicate is a raw function then the ptr_fun adaptor is required, but that will ONLY work for a raw pointer. My difficulty is in finding a direct solution that works for all cases.
Hi, all cases are a lot of cases. Please could you be more explicit on the cases you want to cover. Are you thinking on boost::function<bool(typename InputIterator::value_type)>. What about? template <typename InputIterator, typename Predicate > inline bool all_if(InputIterator first, InputIterator last, Predicate pred) { boost::function<bool(typename InputIterator::value_type)> predicate=pred; return std::find_if(first, last, std::not1( predicate ) ) == last; } Vicente
participants (3)
-
Dean Michael Berris
-
Robert Jones
-
vicente.botet