korona
korona

Reputation: 2229

Visual c++ "for each" portability

I only just recently discovered that Visual C++ 2008 (and perhaps earlier versions as well?) supports for each syntax on stl lists et al to facilitate iteration. For example:

list<Object> myList;

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

I was very happy to discover it, but I'm concerned about portability for the dreaded day when someone decides I need to be able to compile my code in say, gcc or some other compiler. Is this syntax widely supported and can I use it without worrying about portability issues?

Upvotes: 24

Views: 21613

Answers (9)

cdiggins
cdiggins

Reputation: 18203

Your code is indeed not portable.

The following works with the C++ 0x standard and Visual C++ 2010 (which doesn't support the new "ranged for" syntax as far as I can tell).

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

Now you can write:

list<Object> myList;

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

Compare this to the BOOST_FOREACH macro code at http://www.boost.org/doc/libs/1_48_0/boost/foreach.hpp which is not only complex it also has a number of dependencies on other boost libraries.

Upvotes: 1

Peter K&#252;hne
Peter K&#252;hne

Reputation: 3274

For each is not standard C or C++ syntax. If you want to be able to compile this code in gcc or g++, you will need to create an iterator and use a standard for loop.

QuantumPete

[edit] This seems to be a new feature introduced into MS Visual C++, so this is definitely not portable. Ref: http://msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/edit]

Upvotes: 25

Mike Hordecki
Mike Hordecki

Reputation: 97091

If you'd like to use foreach and in the same time you don't want to add additional dependency (such as Boost) - this macro will help you:

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

Upvotes: 6

Luc Touraille
Luc Touraille

Reputation: 82041

Visual C++ "for each" is not standard C++, meaning you won't be able to compile your code on other compilers such as g++. However, the STL proposes std::for_each, but its syntax is a lot less intuitive. Here is its prototype:

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

It takes two iterators defining a valid range, and applies the unary function (or functor) f to each object in this range. You can rewrite your example using std::for_each like this:

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

std::for_each(myList.begin(), myList.end(), foo);

However, if you want to stay close to the classical syntax of the for each construct, and if you're ok about using Boost, you can use BOOST.FOREACH, which will let you write

list<Object> myList;

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

Upvotes: 5

Ferruccio
Ferruccio

Reputation: 100648

I wouldn't use that. While it's a tempting feature, the syntax is incompatible with the upcoming C++0x standard, which uses:

list<Object> myList;

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

to do the same thing.

Upvotes: 35

user21714
user21714

Reputation: 5951

I also recommend BOOST_FOREACH. I usually create a macro along the lines of:

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

This tends to increase readability. You have to be careful about collisions with other foreach implementations though. For instance, Qt provides a 'foreach' and there's the std::for_each.

I find that the std::for_each doesn't actually save much time since you end up making lots of one-off function objects to supply to the for_each call. It's usually just as fast to make standard for-loop using STL iterators.

Upvotes: 0

argatxa
argatxa

Reputation: 520

My vote goes for Luc,

Stick to the standard STL algorithms and you will be better off by far. STL algorithms can make your life very easy, efficient and safe. Take a look at the off the shelve algorithms like find_if, count, count_if, sort, transform, etc...

Point 5 onwards... http://www.sgi.com/tech/stl/table_of_contents.html

Boost is cool, but if you are going to use it just for the FOR_EACH macro it is too much cumbersome regarding the development/build environment setup.

use boost when standard c++ / stl cannot solve the problem in an 'easy' way.

Upvotes: -1

Konrad Rudolph
Konrad Rudolph

Reputation: 545528

There is a very good portable alternative: Boost.Foreach. Just dump this header into your project and you can write your loops as follows:

list<Object> myList;

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

Upvotes: 21

dummy
dummy

Reputation: 4284

The Boost Library has a portable ForEach imlementation.

Upvotes: 2

Related Questions