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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With