我最近才发现 Visual C++ 2008(也许还有更早的版本?)支持for each
stl 列表等语法以促进迭代。例如:
list<Object> myList;
for each (Object o in myList)
{
o.foo();
}
我很高兴发现它,但是当有人决定我需要能够在 gcc 或其他编译器中编译我的代码时,我担心可移植性。这种语法是否得到广泛支持,我可以在不担心可移植性问题的情况下使用它吗?
我最近才发现 Visual C++ 2008(也许还有更早的版本?)支持for each
stl 列表等语法以促进迭代。例如:
list<Object> myList;
for each (Object o in myList)
{
o.foo();
}
我很高兴发现它,但是当有人决定我需要能够在 gcc 或其他编译器中编译我的代码时,我担心可移植性。这种语法是否得到广泛支持,我可以在不担心可移植性问题的情况下使用它吗?
我不会用那个。虽然这是一个诱人的功能,但其语法与即将推出的 C++0x 标准不兼容,该标准使用:
list<Object> myList;
for (Object o : myList)
{
o.foo();
}
做同样的事情。
For each 不是标准的 C 或 C++ 语法。如果您希望能够在 gcc 或 g++ 中编译此代码,则需要创建一个迭代器并使用标准 for 循环。
量子皮特
[编辑] 这似乎是 MS Visual C++ 中引入的一个新特性,所以这绝对不是可移植的。参考: http: //msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/edit]
有一个很好的便携式替代品:Boost.Foreach。只需将此标头转储到您的项目中,您就可以按如下方式编写循环:
list<Object> myList;
BOOST_FOREACH(Object o, myList)
o.foo();
如果您想使用 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;
}
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();
}
Boost 库有一个可移植的ForEach 实现。
您的代码确实不可移植。
以下适用于 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 库有许多依赖关系。
我还推荐 BOOST_FOREACH。我通常按照以下方式创建一个宏:
#define _foreach(x,y) BOOST_FOREACH(x,y)
这往往会增加可读性。不过,您必须小心与其他 foreach 实现的冲突。例如,Qt 提供了一个“foreach”,还有 std::for_each。
我发现 std::for_each 实际上并没有节省太多时间,因为您最终会制作大量一次性函数对象来提供给 for_each 调用。使用 STL 迭代器制作标准 for 循环通常同样快。
我投票给卢克,
坚持标准的 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。