简化简单的C ++代码 - 就像Pythons一样

时间:2010-08-08 14:02:34

标签: c++ python any

现在,我有这段代码:

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()))

大多数情况下,我想知道Boost / STL中是否存在任何现有的any(和all)等价物。或者为什么没有(因为它看起来非常有用,我经常在Python中使用它)。

3 个答案:

答案 0 :(得分:6)

C ++(还)没有foreach构造。你必须自己编写/

也就是说,你可以在这里使用std::find_if算法:

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

此外,您应该使用std::vectorstd::deque而不是std::list

编辑:某事刚刚告诉我这实际上不会编译,因为你的列表包含shared_ptr而不是实际的对象...因此,你要去需要编写自己的仿函数,或者依靠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();
}

注意,我还没有测试过第二个解决方案。

答案 1 :(得分:4)

而不是find_if我会选择自定义。我对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));
}

编辑:替代任何与Billy ONeal的find_if。

答案 2 :(得分:4)

新的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实现了这一目标。