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

Visual C++“为每个”便携性

  •  23
  • korona  · 技术社区  · 16 年前

    我只是最近才发现Visual C++ 2008(也可能是早期版本)?支架 for each STL列表上的语法等有助于迭代。 例如:

    list<Object> myList;
    
    for each (Object o in myList)
    {
      o.foo();
    }
    

    我很高兴发现它,但我担心在可怕的一天,当有人决定我需要能够用say、gcc或其他编译器编译我的代码时,它的可移植性。这种语法是否得到了广泛的支持,我可以在不担心可移植性问题的情况下使用它吗?

    9 回复  |  直到 13 年前
        1
  •  25
  •   D.Shawley    14 年前

    对于每个不是标准的C或C++语法。如果希望能够在gcc或g++中编译此代码,则需要创建迭代器并使用标准for循环。

    量子粒子

    [编辑] 这似乎是MS VisualC++中引入的一个新特性,所以这绝对不是可移植的。裁判: http://msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/编辑]

        2
  •  32
  •   Ferruccio    16 年前

    我不会用那个的。虽然这是一个诱人的特性,但是语法与即将到来的C++ 0x标准不兼容,它使用:

    list<Object> myList;
    
    for (Object o : myList)
    {
       o.foo();
    }
    

    做同样的事。

        3
  •  21
  •   Konrad Rudolph    16 年前

    有一个非常好的便携式替代品: Boost.Foreach . 只需将这个头转储到项目中,就可以编写如下循环:

    list<Object> myList;
    
    BOOST_FOREACH(Object o, myList)
        o.foo();
    
        4
  •  6
  •   Mike Hordecki    16 年前

    如果要使用foreach,同时又不想添加其他依赖项(如boost),则此宏将帮助您:

    #define VAR(V,init) __typeof(init) V=(init)
    #define FOREACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++)
    
    std::vector<int> numbers;
    
    FOREACH(I, numbers)
    {
        std::cout << *I << std::endl;
    }
    
        5
  •  5
  •   Luc Touraille    16 年前

    Visual C++“为每个”不是标准C++,这意味着你将无法编译你的代码在其他编译器,如G++。然而,STL建议 std::for_each 但是它的语法不那么直观。这是它的原型:

    template <class InputIterator, class UnaryFunction>
    UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);
    

    它需要两个迭代器定义一个有效的范围,并将一元函数(或函数)f应用于该范围中的每个对象。 您可以使用std::重写示例,如下所示:

    void foo(Object o)
    {
      o.foo();
    }
    ...
    list<Object> myList;
    
    std::for_each(myList.begin(), myList.end(), foo);
    

    但是,如果您想接近for-each结构的经典语法,并且您对使用boost很满意,那么可以使用 BOOST.FOREACH ,这会让你写

    list<Object> myList;
    
    BOOST_FOREACH(Object o, myList)
    {
        o.foo();
    }
    
        6
  •  2
  •   dummy    16 年前

    Boost库有一个便携式的 ForEach imlementation .

        7
  •  1
  •   cdiggins    13 年前

    您的代码确实不可移植。

    下面的工作与C++ 0x标准和Visual C++ 2010(它不支持新的“远程”语法,据我所知)。

    #define for_each(_ITER_, _COLL_) for (auto _ITER_ = _COLL_.begin(); \
        _ITER_ != _COLL_.end(); _ITER_++)
    

    现在你可以写:

    list<Object> myList;
    
    for_each (o, myList)
    {
      o.foo();
    }
    

    将此代码与处的Boost ForEach宏代码进行比较 http://www.boost.org/doc/libs/1_48_0/boost/foreach.hpp 这不仅很复杂,而且还依赖于其他boost库。

        8
  •  0
  •   user21714    16 年前

    我也推荐Boost ou ForEach。我通常沿着以下几行创建宏:

    #define _foreach(x,y) BOOST_FOREACH(x,y)
    

    这会增加可读性。但是,您必须小心与其他foreach实现的冲突。例如,qt提供了一个“for each”,每个都有std::。

    我发现,std::for-each实际上并没有节省多少时间,因为您最终会生成许多一次性函数对象来提供给for-each调用。使用STL迭代器建立循环标准的速度通常也一样快。

        9
  •  -1
  •   argatxa    16 年前

    我投卢克一票,

    坚持标准的STL算法,到目前为止你会更好。STL算法可以让你的生活非常简单、高效和安全。看一下现成的算法,比如find-if、count、count-if、sort、transform等…

    第5点继续…… http://www.sgi.com/tech/stl/table_of_contents.html

    Boost很酷,但是如果您只对for-each宏使用它,那么在开发/构建环境设置方面就太麻烦了。

    当标准C++/STL不能以“容易”的方式解决问题时,使用Boost。