开发者

is there prettier syntax for a c++ iterator?

开发者 https://www.devze.com 2023-03-28 03:14 出处:网络
Is there a prettier / less-verbose way to use iterators in C++? From the tutorials I\'ve seen, I eithe开发者_JAVA百科r set up typedefs everywhere (which gets tedious to do for a lot of one-off for-loo

Is there a prettier / less-verbose way to use iterators in C++? From the tutorials I've seen, I eithe开发者_JAVA百科r set up typedefs everywhere (which gets tedious to do for a lot of one-off for-loops):

typedef std::vector<std:pair<int, int> >::iterator BlahIterator;

or have verbose-looking for loops like:

for (std::vector<std:pair<int, int> >::iterator it = ... ) ...

Is there a better way?


In C++11 you can use the range-based for loop combined with the auto keyword:

for (auto& it : v) ...


With boost, you can use the FOR_EACH macro.

typedef pair<int, int> tElem;
BOOST_FOREACH( tElem e, aVector )
{
    cout << e.first << " " << e.second << '\n';
}


The algorithms sort of get around that particular problem.
Especially with the new lambda functions.

std::for_each(c.begin(), c.end(), Action()); /* Where Action is your functor */

Or with lambda:

std::for_each(c.begin(), c.end(), [](type const& e) { /* Stuff */ });

Note: don't fall into the trap of using std::for_each to replace all loops. There are a whole bunch of algorithms that use iterators that allow you to manipulate or do operations based on the contents of a container.


With c++0x you can use the auto keyword:

for (auto i = v.begin(); i != v.end(); ++i) {}


I usually use the following naming pattern:

typedef std::pair<int, int> Blah;
typedef std::vector<Blah> Blahs;

and then use Blahs::iterator, i.e I don't name the iterator but the container (and usually the thing contained in it).
typedef is a very useful abstraction mechanism.

Note that a vector of "Blah" is called "Blahs" (i.e. just the plural), not a "BlahVector", because the specific container doesn't matter.


One possibility is to write your loop (or whatever code that uses the iterator) into a small generic algorithm of its own. By making it a template, the compiler can/will deduce the iterator type automatically:

template <class T>
do_something(T begin, T end) { 
    for (T pos = begin; pos != end; ++pos) 
        do_something_with(*pos);
}


I usually define this, though I've been told I'm going to hell for it:

#define forsn(i, s, n) for(int i = (s); i < (n); ++i)
#define forn(i, n) forsn(i, 0, n)
#define forall(it, g) for(typeof g.begin() it = g.begin(); it != g.end(); ++it)

Then, to loop from 0 to n, a common task, I say forn(i, n) foo(i);, and to loop any standard container c, I say forall(it, c) foo(it); Do note that typeof is a GCC extension to the standard.

0

精彩评论

暂无评论...
验证码 换一张
取 消