3

I was wondering either it is possible in the c++11 syntax to use the new container based for loop for multiple items, for example:

std::vector<double> x;
std::vector<double> y;

for (double& xp, yp : x, y)
{
     std::cout << xp << yp << std::endl;
}

I was not able to find any information about using this loop for more than one container. I would appreciate all help.

Example effect in the classic for loop:

std::vector<double>::iterator itX = m_x.begin();
std::vector<double>::iterator itY = m_y.begin();

for (uint32_t i = 0; i < m_x.size(); i++, itX++, itY++)
{
    // operations on the m_x and m_y vectors
}
manlio
  • 18,345
  • 14
  • 76
  • 126
Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74
  • What would you like that syntax to mean? Cartesian product or lockstep iteration? And what happens if the containers don't have the same size? – Mat Jun 08 '15 at 09:16
  • 1
    It's not even obvious what this should do. Pair items by index? In that case, what if the vectors have different lengths? Or iterate over the cross product? Anyway, no, it's not possible with the syntax you give either way, but what is possible depends on what you want. Can you explain your question in more detail? –  Jun 08 '15 at 09:17
  • Yes I assume that containers are the same size. I would like to get an item from each container rach step. If they would be different size i gues a segmentation fault would occur. – Łukasz Przeniosło Jun 08 '15 at 09:17
  • 1
    IIRC EWG is quite interested in some sort of syntax to permit simultaneous iteration over multiple ranges. But nothing in the current language supports this; you'd need some library help. – T.C. Jun 08 '15 at 09:19
  • Thats Ok, in that case I will just use oldschool for loop – Łukasz Przeniosło Jun 08 '15 at 09:20
  • Take a look at: http://stackoverflow.com/a/12553437/1147772 – Drax Jun 08 '15 at 09:24

2 Answers2

5

There is a request in the language working group to support a very similar syntax to iterate simultaneously on many containers:

Section: 6.5.4 [stmt.ranged] Status: Open Submitter: Gabriel Dos Reis

Opened: 2013-01-12 Last modified: 2015-05-22

Discussion:

The new-style 'for' syntax allows us to dispense with administrative iterator declarations when iterating over a single sequence. The burden and noise remain, however, when iterating over two or more sequences simultaneously. We should extend the syntax to allow that. E.g. one should be able to write:

for (auto& x : v; auto& y : w)
  a = combine(v, w, a);

instead of the noisier

auto p1 = v.begin();
auto q1 = v.end();
auto p2 = w.begin();
auto q2 = w.end();
while (p1 < q1 and p2 < q2) {
   a = combine(*p1, *p2, a);
   ++p1;
   ++p2;
}

See http://cplusplus.github.io/EWG/ewg-active.html#43

So it could happen but not in the near future.

Meanwhile the best choice is probably the classical for loop.

manlio
  • 18,345
  • 14
  • 76
  • 126
2

I know this is a little old now, but I had a similar query and T.C.'s "you'd need some library help" comment made me grin, because I ended up solving a similar issue with only a few extra characters. To recycle the OP's first example, and assuming as stated that the vectors are guaranteed the same size, you can make C++11 referencing meet old-school pointer arithmetic, like so:

std::vector<double> x;
std::vector<double> y;

for (double &xp:x)
{
   std::cout << xp << y[&xp-&x[0]] << std::endl;
}

Probably best not used in production code (I'm a self-taught hobbyist coder, so meh) but it works well enough, is simple, requires no libraries and does not seem to suffer any notable speed penalty (at least, that I've noticed). It even works in minimal C++11 environments (such as VC11). To be clear, I used this in a slightly different context, where (given the above example) I only accessed y[] when a change was actually required (so any possible speed reduction is mitigated in the noise), but since the y[] access was required at the same index as in x[] and required no extra variables/iterators, it fit the bill perfectly.

Also, +1 for manlio's answer; would you believe I actually tried to use exactly that syntax intuitively before I went looking for an alternative? :O