+18  A: 

You just have to understand the first statement is a declaration (and that comma is not the comma operator). It's not any harder to do:

for (int i, double d; ...)

Than it is:

int i, double d;

Because for (init cond; expr) statement gets expanded to:

{
    init
    while (cond)
    {
        statement
        expr;
    }
}

A trick is to make that init statement a struct definition and instance, like:

for (struct { int myIndex; MyElement* ptr;} data = {0, Pool->First};
    data.ptr;
    ++data.myIndex, data.ptr = data.ptr->next)
    {
        // blah...
    }

Which becomes the same as:

{
    struct
    {
        int myIndex;
        MyElement* ptr;
    } data = {0, Pool->First};

    while (data.ptr)
    {
        {
            // blah...
        }
        ++data.myIndex, data.ptr = data.ptr->next;
    }
}

But I find that pretty ugly. In practice, I'd just split it up like you have. If scope is really a problem, which it probably isn't, throw the extra braces around there.

I don't think there's much to improve here without a bit of boilerplate code.

GMan
Oh that's an ugly solution, I'm kinda glad I didn't think of it. :-) I too much prefer putting the loop in its own block.
Omnifarious
Answer accepted. There doesn't seem a more elegant way than defining the variables outside the for-loop and putting the whole block between braces.
Patrick
+1 for thinking outside the box! But yes, ugly! :-)
Steve Folly
@Martin: Note that an `init` statement ends with `;`, so putting it into the equivalence is redundant/erroneous. (See §6.5.3.)
GMan
@GMan: Sorry. :-)
Martin York
@Martin: It's all good. :) Thanks for taking care of answers.
GMan
What about also adding an operator++ to your struct? :)
miked
@miked: That's what I meant by boilerplate code. :) If I were to do that, I'd make it more generic...I wonder how generic it can be made.
GMan
+2  A: 

At least C++ allows us to declare variables in the if clause, which which is sometimes used to declare a variable that only is only visible when some condition is true:

if (MyElement *ptr=Pool->First) // block is only entered when ptr!=0
{
 for (int myIndex=0;ptr;++myIndex,ptr=ptr->next)
 {
 }
}
// ptr is out of scope now.

This could be a method to limit the scope of ptr and index, while maintaining readability.

Luther Blissett
There is really no need for the if statement. You can add braces (almost) anywhere you like to set up a new scope.
Dennis Zickefoose
The `if() for() ...` pattern works also well with macros.
Luther Blissett
+6  A: 

If I really wanted to confine the scope to the loop I would use:

#include <utility>
for (auto i = std::make_pair(0,Pool->First);
     i.second;
     ++i.first, i.second=i.second->next)
Peter G.
But now you loose all the information that was given by the variables names: `i.first` and `i.second` do not convey any information about the purpose of the variables, whereas `myIndex` and `ptr` give some (not a lot, but some).
Luc Touraille
Yes, there is a tradeoff to make here - I would say it is the standard tradeoff when using pair. If the purpose of the pair members is evident I would stick to pair. If not I would switch to a solution with explicit names.
Peter G.