Henry Henrinson
Henry Henrinson

Reputation: 5412

Declaring several new counters in a for loop

Consider the following code:

vector<int> v;
for(vector<int>::iterator vi = n.begin(), int i = 0;
    vi != n.end();
    ++vi, ++i){}

Is there a reason why this is not allowed? I want to be able to define 2 new counters, both vi and the index i.

Upvotes: 4

Views: 203

Answers (6)

Casey
Casey

Reputation: 10946

If you want to use two variables of differing type in a for loop, one must be declared outside the scope of the for loop. You can enforce the scope of the second one by enclosing the loop inside a set of braces:

vector<int> v;
{
int i = 0;
for(vector<int>::iterator vi = n.begin(); vi != n.end(); ++vi, ++i) { /* DO STUFF */ }
} //i's scope ends here.

Upvotes: 2

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385325

The answer is "there isn't really any reason other than the syntax requires it".

I can imagine, though, that code could get very complex if it were allowed, so that's a good reason not to add support for this into the language.

You can create your own scope to bound it instead:

std::vector<int> v;
{
   std::vector<int>::iterator it = n.begin(), end = n.end();
   int i = 0;

   for ( ; it != end; ++it, ++i)
   {}
}

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254691

Is there a reason why this is not allowed?

Because the arcane declaration syntax of C++ doesn't allow you to declare objects of unrelated types in the same declaration statement; and the initialiser of a for loop only allows a single declaration statement.

I want to be able to define 2 new counters, both vi and the index i.

You could declare one or both outside the loop, if you don't mind polluting the surrounding block. Otherwise, you could put them in a stucture:

for (struct {vector<int>::iterator vi; int i;} x = {n.begin(), 0}; 
     x.vi != n.end();
     ++x.vi, ++x.i) {}

Upvotes: 2

Yu Hao
Yu Hao

Reputation: 122493

This is the explanation from the book C++ Primer:

As in any other declaration, init-statement can define several objects. However, init-statement may be only a single declaration statement. Therefore, all the variables must have the same base type. As one example, we might write a loop to duplicate the elements of a vector on the end as follows:

// remember the size of v and stop when we get to the original last element

for (decltype(v.size()) i = 0, sz = v.size(); i != sz; ++i)

    v.push_back(v[i]);

In this loop we define both the index, i, and the loop control, sz, in init-statement.

This makes sense, the syntax of for loop is:

C++11 §6.5.3 The for statement [stmt.for]

The for statement

for ( for-init-statement ; condition opt ; expression opt ) statement

for-init-statement is one statement only. Declaration two different types of variables would make it at least two statements.

Upvotes: 4

Alden
Alden

Reputation: 2269

A look at the comma operator wikipedia page would help, specifically the first example.

int a=1, b=2, c=3, i=0; // comma acts as separator in this line, not as an operator 

Also, why not do something like this?

vector<int> v;
vector<int>::iterator vi = n.begin();
int i = 0;
for(; vi != n.end(); ++vi, ++i)
{
}

Upvotes: 0

Thomas Ayoub
Thomas Ayoub

Reputation: 29451

You can only write one declaration statement, but it can define multiple variables, e.g.:

for ( int i = 0, j = 10 ; ... )

Upvotes: 1

Related Questions