Visual C ++“为每个”可移植性

时间:2008-10-13 12:21:29

标签: c++ visual-c++ stl foreach

我最近刚刚发现Visual C ++ 2008(也许还有早期版本?)支持stl list等的for each语法以促进迭代。 例如:

list<Object> myList;

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

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

9 个答案:

答案 0 :(得分:32)

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

list<Object> myList;

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

做同样的事情。

答案 1 :(得分:25)

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

QuantumPete

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

答案 2 :(得分:21)

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

list<Object> myList;

BOOST_FOREACH(Object o, myList)
    o.foo();

答案 3 :(得分: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;
}

答案 4 :(得分: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);

但是,如果你想要接近每个构造的经典语法,并且如果你可以使用Boost,你可以使用BOOST.FOREACH,这将让你写

list<Object> myList;

BOOST_FOREACH(Object o, myList)
{
    o.foo();
}

答案 5 :(得分:2)

Boost Library有一个便携式ForEach imlementation

答案 6 :(得分: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库有许多依赖关系。

答案 7 :(得分:0)

我也推荐BOOST_FOREACH。我通常会创建一个宏:

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

这往往会提高可读性。但是,您必须小心与其他foreach实现的冲突。例如,Qt提供了一个'foreach',而且还有std :: for_each。

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

答案 8 :(得分:-1)

我的投票是Luc,

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

相关问题