23

我最近才发现 Visual C++ 2008(也许还有更早的版本?)支持for eachstl 列表等语法以促进迭代。例如:

list<Object> myList;

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

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

4

9 回答 9

33

我不会用那个。虽然这是一个诱人的功能,但其语法与即将推出的 C++0x 标准不兼容,该标准使用:

list<Object> myList;

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

做同样的事情。

于 2008-10-13T14:24:38.317 回答
25

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

量子皮特

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

于 2008-10-13T12:23:03.100 回答
21

有一个很好的便携式替代品:Boost.Foreach。只需将此标头转储到您的项目中,您就可以按如下方式编写循环:

list<Object> myList;

BOOST_FOREACH(Object o, myList)
    o.foo();
于 2008-10-13T12:31:05.843 回答
6

如果您想使用 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;
}
于 2008-10-13T15:11:03.463 回答
5

Visual C++“for each”不是标准的 C++,这意味着您将无法在其他编译器(例如 g++)上编译您的代码。然而,STL 提出了std::for_each,但它的语法不那么直观。这是它的原型:

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

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

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();
}
于 2008-10-13T12:36:44.227 回答
2

Boost 库有一个可移植的ForEach 实现

于 2008-10-13T12:29:44.117 回答
1

您的代码确实不可移植。

以下适用于 C++ 0x 标准和 Visual C++ 2010(据我所知,它不支持新的“ranged for”语法)。

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

现在你可以写:

list<Object> myList;

for_each (o, myList)
{
  o.foo();
}

将此与http://www.boost.org/doc/libs/1_48_0/boost/foreach.hpp上的 BOOST_FOREACH 宏代码进行比较,这不仅复杂,而且还对其他 boost 库有许多依赖关系。

于 2012-01-03T15:33:17.200 回答
0

我还推荐 BOOST_FOREACH。我通常按​​照以下方式创建一个宏:

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

这往往会增加可读性。不过,您必须小心与其他 foreach 实现的冲突。例如,Qt 提供了一个“foreach”,还有 std::for_each。

我发现 std::for_each 实际上并没有节省太多时间,因为您最终会制作大量一次性函数对象来提供给 for_each 调用。使用 STL 迭代器制作标准 for 循环通常同样快。

于 2008-10-13T13:56:44.987 回答
-1

我投票给卢克,

坚持标准的 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。

于 2008-10-13T13:39:27.017 回答