упростить простой код C ++ - что-то вроде Pythons любой - PullRequest
5 голосов
/ 08 августа 2010

Прямо сейчас, у меня есть этот код:

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

    return false;
}

Я использовал Boost здесь и тогда, но я не мог вспомнить какой-либо простой способ написать его так, как я мог бы написать его на Python,Например:

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

Есть ли какая-либо конструкция в STL / Boost, чтобы написать ее более или менее так?

Или, возможно, эквивалент этого кода Python:

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

В основном мне интересно, существует ли какой-либо существующий anyall) эквивалент в Boost / STL.Или почему нет (потому что это кажется довольно полезным, и я часто использую его в Python).

Ответы [ 3 ]

6 голосов
/ 08 августа 2010

C ++ (пока) не имеет конструкции foreach. Вы должны написать это сами /

Тем не менее, вы можете использовать алгоритм std::find_if здесь:

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

Кроме того, вы, вероятно, должны использовать std::vector или std::deque вместо std::list.

EDIT: sth только что сообщил мне, что это на самом деле не скомпилируется, потому что ваш список содержит shared_ptr вместо реальных объектов ... из-за этого вам нужно будет написать свой собственный функтор или положитесь на повышение:

//#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();
}

Обратите внимание, я не проверял это второе решение.

4 голосов
/ 08 августа 2010

Новый стандарт C ++ имеет std :: any_of, например,

bool isAnyTrue()
{
    return std::any_of(mylist.begin(), mylist.end(), std::mem_fn(&Foo::isTrue)); // Note std::mem_fn and not std::mem_fun
}

В VS2010 это реализовано.

4 голосов
/ 08 августа 2010

Вместо find_if я бы пошел с обычаем any. Мне больше нравится с точки зрения читабельности, чем find_if, но это дело вкуса.

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));
}

Редактировать: Альтернатива any с find_if от Billy ONeal.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...