Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using declaration in condition part of FOR-loop statement

Tags:

c++

for-loop

Reading http://en.cppreference.com/w/cpp/language/for I find, that condition part of for loop can be either expression, contextually convertible to bool, or single-variable-declaration with mandatory brace-or-equal initializer (syntax specification in 6.4/1):

condition:

  • expression
  • type-specifier-seq declarator = assignment-expression

But I have never seen a using of the later in a source code.

What is the profitable (in sense of brevity, expressiveness, readability) making use of variable declaration in condition part of for loop statement ?

for (int i = 0; bool b = i < 5; ++i) {
    // `b` is always convertible to `true` until the end of its scope
} // scope of `i` and `b` ends here

Variable declared in condition can be only convertible to true during whole period of lifetime (scope) if there no side effects influencing on result of convertion to bool.

I can imagine only a couple of use cases:

  • declaration a variable of class type, having user-defined operator bool.
  • some kind of changing cv-ref-qualifiers of loop variable:

    for (int i = 5; int const & j = i; --i) {
        // using of j
    }
    

But both of them are very artifical.

like image 755
Tomilov Anatoliy Avatar asked Mar 27 '26 04:03

Tomilov Anatoliy


1 Answers

All three statements if, for and while can be used in a similar way. Why is this useful? Sometimes it just is. Consider this:

Record * GetNextRecord();         // returns null when no more records
Record * GetNextRecordEx(int *);  // as above, but also store signal number

// Process one
if (Record * r = GetNextRecord()) { process(*r); }

// Process all
while (Record * r = GetNextRecord()) { process(*r); }

// Process all and also keep some loop-local state
for (int n; Record * r = GetNextRecordEx(&n); )
{
    process(*r);
    notify(n);
}

These statements keep all the variables they need at the minimal possible scope. If the declaration form wasn't allowed inside the statement, you would need to declare a variable outside the statement but you would only need it for the duration of the statement. That means you would either leak into too large a scope, or you would need unsightly extra scopes. Allowing the declaration inside the statement offers a convenient syntax, which although rarely useful is very nice to have when it is useful.

Perhaps the most common-place use case is in a multiple-dispatch cast situation like this:

if (Der1 * p = dynamic_cast<Der1 *>(target)) visit(*p);
else if (Der2 * p = dynamic_cast<Der2 *>(target)) visit(*p);
else if (Der3 * p = dynamic_cast<Der3 *>(target)) visit(*p);
else throw BadDispatch();

As an aside: only the if statement admits a code path for the case where the condition is false, given in an optional else block. Neither while nor for allow you to consume the result of the boolean check in this way, i.e. there is no for ... else or while ... else construction in the language.

like image 198
Kerrek SB Avatar answered Mar 28 '26 18:03

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!