代码之家  ›  专栏  ›  技术社区  ›  Albert

简化简单的C++代码——像Python一样

  •  5
  • Albert  · 技术社区  · 14 年前

    现在,我有这个代码:

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

    大部分我想知道是否有 any (和) all )相当于boost/stl。或者为什么没有(因为它看起来非常有用,而且我经常在Python中使用它)。

    3 回复  |  直到 14 年前
        1
  •  6
  •   Billy ONeal IS4    14 年前

    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 .

    编辑: 某物 刚刚告诉我这不会真正编译,因为您的列表包含 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();
    }
    

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

        2
  •  4
  •   pmr    14 年前

    如果我要按惯例去的话,就不要找你。在可读性方面,我更喜欢它,而不是“如果”,但这是一个品味问题。

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

    编辑:选择任何一个与发现如果由比利奥尼尔。

        3
  •  4
  •   ronag    14 年前

    新的C++标准具有STD::

    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已经实现了这一点。