简化简单的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 个回答
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这个版本已经实现了这个功能。
4
与其使用 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));
}
补充:Billy ONeal 提供的用 find_if 实现的替代 any。
6
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
。
补充说明:sth 刚刚告诉我,这段代码实际上是不能编译的,因为你的列表里存的是 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();
}
需要注意的是,我还没有测试这个第二个解决方案。