Thanks. That seems to indicate that there are at least two about equally
convincing but exactly opposite notions of what `else` should mean if it
were introduced as an extension to `for`...
---
Anyway I find your example interesting because it's easier to read, and
therefore grok, than my example that, more ideally, constrains the scope
for modification of the variable.
And I think that's due to two reasons:
• That your example is shorter, mainly because of formatting.
• That C++, from its C heritage, supports the changing-variables style
of coding, and does not so much support expression based coding.
In some other contexts the shorter formatting tends to produce what in
my eyes is a gray wall of compact code, so I'm wary of adopting it. It's
nice for books and articles, though, where vertical space is a limited
resource. But on the third and gripping hand I may be too old to change
formatting preferences again...
---
Going back even further historically, C's parent language BCPL had a
construct that one can think of as “arithmetic blocks”, like a curly
braces compound statement that could return a value.
And expressing your example with an imaginary such construct it's not
significantly more to read, and then properly constrains the scope where
the code can change or influence the value of the boolean:
const bool loop_body_executed = BCPL_BLOCK {
for (INIT; COND; UPDATE) {
if( SOMETHING ) { return true; }
}
return false;
};
if( not loop_body_executed ) {
// The logical "else" part.
}
---
As it happens it's easy to define a macro like BCPL_BLOCK:
#define BCPL_BLOCK ~[&]()
... where the `~` operator is defined as e.g.
namespace lambda_support
{
using std::declval;
template< class Func
, class Enabled_ = decltype( declval<Func>()() )
>
inline auto operator~( Func const& f )
-> decltype(( f() ))
{ return f(); }
} // namespace lambda_support
One just needs a `using` statement for it. Hence the need for SFINAE to
ensure that this definition only kicks in, that it's only found, when
`~` is applied to something callable without arguments. It should
probably be even more constrained than what I managed above.
So, that notation is not hypothetical. It's also easy to provide
bindings for the lambda, e.g. using the `%` operator. It would be (or
was when I tried it out, some years ago, then named `$invoked_with`
instead of BCPL_BLOCK) a rather ugly hack that didn't entirely prevent
incorrect use, but if one could get language and/or standard library
support then it could be safe, because the standard library is allowed
to use magic. I'd prefer a core language prefix invocation operator.
Cheers!,
- Alf