Re: Using for each, in with STL containers with non-const iterators
Wyck wrote:
I want to use the "for each, in" syntax with an STL container, and still
modify the elements of the container while iterating.
I was expecting this to work:
std::vector<int> lst;
lst.push_back(1);
lst.push_back(2);
lst.push_back(3);
for each( int& num in lst ) {
num++;
}
for each is a VC8 language extension, and not valid C++.
But it gives the error:
'static_cast' : cannot convert from 'const int' to 'int &'
Why is it using a const iterator when i'm using a reference type?
I think it is passing the elements as rvalues, not lvalues, so you can't
bind them to a non-const reference. However, since this is an extension
mainly designed for use with C++/CLI, and one that is not properly
documented, who knows?
Is there
a way to do this?
You could use BOOST_FOREACH instead, which is valid C++ and which does
support references, though this isn't yet part of an official boost
release. You can get it from the CVS though:
http://boost.cvs.sourceforge.net/boost/boost/boost/foreach.hpp?revision=1.35&view=markup
http://sourceforge.net/cvs/?group_id=7586
http://www.boost.org
I think the code would be:
BOOST_FOREACH(int& num, lst) {
num++;
}
(you can do #define foreach BOOST_FOREACH or similar).
This is valid code:
for each( const int& cref in lst ) { /**/ }
...but 'cref' is not an l-value
It is (references are by definition named l-values). However, it isn't
modifiable.
, so you can't modify the elements of the
list while iterating!
True.
And this is valid code:
for each( int clone in lst ) { /**/ }
...but 'clone' is a copy of the element, not the original. Any changes to
'clone' are not reflected in the original 'lst' array elements.
To work around I would write it using traditional syntax:
for( std::vector<int>::iterator i=lst.begin(); i!=lst.end(); ++i ) {
(*i)++;
}
But how do I use "for each, in" with STL containers (in unmanaged non CLR)
and still modify the elements of the containter?
You don't, but using C++/CLI extensions in normal C++ is not really a
good idea in any case. std::transform would work here.
Tom