5

现在,我有这个代码:

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 中使用它)。

4

3 回答 3

6

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

也就是说,您可以在std::find_if此处使用该算法:

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

此外,您可能应该使用std::vectororstd::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();
}

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

于 2010-08-08T14:13:25.833 回答
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));
}

编辑:使用比利 ONeal 的 find_if 替代 any。

于 2010-08-08T14:16:45.873 回答
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 实现了这一点。

于 2010-08-08T15:36:28.590 回答