Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simplify simple C++ code -- something like Pythons any

Tags:

c++

python

any

Right now, I have this code:

bool isAnyTrue() {
    for(std::list< boost::shared_ptr<Foo> >::iterator i = mylist.begin(); i != mylist.end(); ++i) {
        if( (*i)->isTrue() )
            return true;
    }

    return false;
}

I have used Boost here and then but I couldn't really remember any simple way to write it somewhat like I would maybe write it in Python, e.g.:

def isAnyTrue():
    return any(o.isTrue() for o in mylist)

Is there any construct in STL/Boost to write it more or less like this?

Or maybe an equivalent to this Python Code:

def isAnyTrue():
    return any(map(mylist, lambda o: o.isTrue()))

Mostly I am wondering if there is any existing any (and all) equivalent in Boost / STL yet. Or why there is not (because it seems quite useful and I use it quite often in Python).

like image 948
Albert Avatar asked Aug 08 '10 14:08

Albert


2 Answers

C++ does not (yet) have a foreach construct. You have to write that yourself/

That said, you can use the std::find_if algorithm here:

bool isAnyTrue()
{
    return std::find_if(mylist.begin(), mylist.end(), std::mem_fun(&Foo::isTrue))
           != mylist.end();
}

Also, you should probably be using std::vector or std::deque rather than std::list.

EDIT: sth has just informed me that this won't actually compile because your list contains shared_ptr instead of the actual objects... because of that, you're going to need to write your own functor, or rely on boost:

//#include <boost/ptr_container/indirect_fun.hpp>

bool isAnyTrue()
{
    return std::find_if(mylist.begin(), mylist.end(), 
           boost::make_indirect_fun(std::mem_fun(&Foo::isTrue))) != mylist.end();
}

Note, I haven't tested this second solution.

like image 57
Billy ONeal Avatar answered Sep 26 '22 06:09

Billy ONeal


Instead of find_if I'd go with a custom any. I like it better in terms of readability over find_if but that's a matter of taste.

template<class ForwardIterator, class Pred>
bool any(ForwardIterator begin, ForwardIterator end, Pred pred) {
  for( ; begin != end; ++begin)
    if(pred(*begin)) return true;

  return false;

  //or
  //return std::find_if(mylist.begin(), mylist.end(), std::mem_fun(&Foo::isTrue))
  //       != mylist.end();

}

bool isAnyTrue() {
  return any(mylist.begin(), mylist.end(), std::mem_fun(&Foo::isTrue));
}

Edit: Alternative any with find_if by Billy ONeal.

like image 33
pmr Avatar answered Sep 22 '22 06:09

pmr