 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ed Avis Guest
|
Posted: Thu Jun 26, 2003 7:35 pm Post subject: Re: Using bool values as loop indexes |
|
|
Other languages have a 'foreach' construct, which might look something
like
foreach bool b (false, true) {
// do something with b
}
Now I know the standard library has for_each(), but it seems a bit
heavyweight to construct a container with two bools and then iterate
over it. Also you must define a function for the loop body, though
various 'lambda' libraries can sometimes make that a bit easier.
I wonder if for simple cases a template function could be written?
For_each<bool, VALUES_2(false, true)>(some_function_taking_bool);
where VALUES_2 expands to one of those compile-time lists (a list of
values, mind you, not a list of types) that certain columnists always
go on about - something like cons<false, cons.
Here I have made some_function an ordinary parameter of the function,
but you could make it a template parameter instead for extra inlining
goodness. Then the code would combine down to just two calls to this
function, one with false and one with true.
Does any existing 'library of weird template stuff' provide such a
foreach loop?
--
Ed Avis <ed (AT) membled (DOT) com>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andrey Tarasevich Guest
|
Posted: Thu Jun 26, 2003 7:40 pm Post subject: Re: Using bool values as loop indexes |
|
|
Tom Houlder wrote:
| Quote: | ...
Nice, but a bit too obfuscated for my taste. And there is no need to
pull any "simple circular nature" into this. For those who like
packing
several actions into one statement, my version can be transformed
into
the following
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
} while (!b++);
} while (!a++);
But normally I refrain from doing that in practice.
I hope you do, as postfix incrementing a bool is deprecated and in
the future it will most likely be an ill-formed program. Indeed,
prefix
increment is also deprecated as stated in 5.2.6 and 5.3.2 but,
AFAICS, erroneously not listed in Appendix D.
|
My previous statement was actually about combining several relatively
independent actions into one statement, like stuffing any
side-effect-producing operators into an logical expression used as an
argument of '} while ()'.
Whether the above use of increment operator is deprecated or not is
rather irrelevant here, since the OP's message was already applying an
increment operator to a 'bool' object. It is his choice, not main.
--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Thu Jun 26, 2003 10:27 pm Post subject: Re: Using bool values as loop indexes |
|
|
No comment on the code supplied for the subject question. I have
no idea why something other than a loop would be used to write a
loop.
On 25 Jun 2003 19:29:05 -0400, "Jeff Greif"
<jgreif (AT) spam-me-not (DOT) alumni.princeton.edu> wrote:
| Quote: | Is it possible to construct a functor and evaluate its operator() in the
same expression? This does not work in the compiler I tried (gcc 3.2
prerelease):
Functor(args)();
Instead I had to do use two statements:
Functor f(args);
f();
|
Same compiler, works fine. Post minimal code. Here is mine.
struct F {
F (int) { }
bool operator() () { return true; }
};
int main () {
F(42)();
}
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Thu Jun 26, 2003 10:32 pm Post subject: Re: Using bool values as loop indexes |
|
|
On 25 Jun 2003 19:35:52 -0400, "News Admin" <news (AT) news (DOT) demon.net> wrote:
| Quote: | for( bool a = false; a < true; ++a){
for(bool b = false; b
std::cout << a << " " << b << " " << a && !b << std::endl;
}
}
Since that is clearly what the poster meant. (The difference is =
substituting "<" for "<=").
|
I don't think so. Run it. One line of output. The poster wanted
four lines of output.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Thu Jun 26, 2003 10:32 pm Post subject: Re: Using bool values as loop indexes |
|
|
On 25 Jun 2003 19:38:04 -0400, Andrey Tarasevich
<andreytarasevich (AT) hotmail (DOT) com> wrote:
| Quote: | Not bad. Did you consider the simple circular nature of the
problem? It is like traversing a non-empty circular list.
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << std::endl;
} while (b = ! b);
} while (a = ! a);
...
Nice, but a bit too obfuscated for my taste.
|
Is it obfuscated like x = (x + 1) % n or x = 1 - x ? I'm serious,
I do not understand.
| Quote: | And there is no need to pull any "simple circular nature" into this.
|
It is a general pattern. If you want to cover all cases, you use
do-while with an increment before the first test. The test is for
not first value. The code that Becker posted can also be written
this way rather than using a larger range type. For unsigned, it
works fine and bool is unsigned. For signed it is undefined but
usually does what is expected like Pete said. If you want only
all positives for signed types a modified test works.
unsigned short i(0);
do {
something_with(i);
++ i;
} while (i != 0);
short i(SHORT_MIN);
do {
something_with(i);
++ i;
} while (i != SHORT_MIN);
// technically, undefined behavior, but typically works fine
for (short i = 0; i >= 0; ++i)
// technically, undefined behavior, but typically works fine
for (short i = 0; i >= 0; i = i == SHORT_MAX ? -42 : i + 1)
// no undefined behavior here
BTW, your abortive do-while reminded me of the general solution.
With the abort, there is no difference between while and do-while.
I keep forgetting that there are times when do-while is the answer.
| Quote: | For those who like packing several actions into one statement,
|
Just a concise way to use the pattern. If that is the only objection,
use two statements to keep the pattern nice.
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
b = ! b;
} while (b);
a = ! a;
} while (a);
| Quote: | my version can be transformed into
the following
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << (a && !b) << std::endl;
} while (!b++);
} while (!a++);
But normally I refrain from doing that in practice.
|
That's good because prefix/postfix increment is depricated for bool and
there is no decrement. It was a mistake to have something like an
unsigned integral type with pseudo arithmetic which is not circular.
Let x be false and y be true, then ++ x == true, x + 1 == true,
++ y == true, y + 1 != true. Of course, you would also want to be able
to run the loop backwards to give true before false as the philosophers
use. Change the initialization and test but not the increment.
bool a(true);
do {
something_with(a);
a = ! a;
} while (! a);
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
KIM Seungbeom Guest
|
Posted: Fri Jun 27, 2003 4:45 pm Post subject: Re: Using bool values as loop indexes |
|
|
Pete Becker <petebecker (AT) acm (DOT) org> wrote
| Quote: |
There's always a problem when you try to loop up to and including the
largest representable value for any type.
The solution is to use a larger type and convert to the type you need:
for (unsigned i = 0; i <= USHRT_MAX; ++i)
// okay, if unsigned is larger than unsigned short
for (int i = 0; i <= SHRT_MAX; ++i)
// okay, if unsigned is larger than unsigned short
for (int i = 0; i < 2; ++i)
bool b = i;
|
Your solution is not always feasible;
what if the loop is from 0 to ULONG_MAX?
I would suggest exiting the loop before the increment:
for (unsigned long i = 0; /* i <= ULONG_MAX */; ++i) {
// do something
if (i == ULONG_MAX) break;
}
For bools:
for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}
Nothing to worry about the type conversion.
--
KIM Seungbeom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andrey Tarasevich Guest
|
Posted: Fri Jun 27, 2003 4:47 pm Post subject: Re: Using bool values as loop indexes |
|
|
John Potter wrote:
| Quote: | ...
Not bad. Did you consider the simple circular nature of the
problem? It is like traversing a non-empty circular list.
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << std::endl;
} while (b = ! b);
} while (a = ! a);
...
Nice, but a bit too obfuscated for my taste.
Is it obfuscated like x = (x + 1) % n or x = 1 - x ? I'm serious,
I do not understand.
|
I'm just referring to using the '} while(...)' part of the code to both
modify the value of the index and verify the resultant value.
| Quote: | And there is no need to pull any "simple circular nature" into
this.
It is a general pattern. If you want to cover all cases, you use
do-while with an increment before the first test. The test is for
not first value. The code that Becker posted can also be written
this way rather than using a larger range type. For unsigned, it
works fine and bool is unsigned. For signed it is undefined but
usually does what is expected like Pete said. If you want only
all positives for signed types a modified test works.
unsigned short i(0);
do {
something_with(i);
++ i;
} while (i != 0);
|
I prefer a different general pattern
unsigned short i(0);
do {
something_with(i);
if (i == USHORT_MAX)
break;
++i;
} while (true);
This version does not impose the requirement that the arithmetic of the
index type is circular and can be easily modified to run the loop
backwards. Of course, in this form it is not as polymorphic with regard
to unsigned types as your version, since it explicitly mentions
'USHORT_MAX'. But this could be easily corrected by using
'std::numeric_limits'.
| Quote: | BTW, your abortive do-while reminded me of the general solution.
With the abort, there is no difference between while and do-while.
I keep forgetting that there are times when do-while is the answer.
|
I prefer using 'do {...} while (...)' to implement cycles, whose bodies
are entered unconditionally, including 'exit from the middle' type of
cycle ('do {...} while (true)'). Others probably might prefer using
something like 'for (; '.
| Quote: | ...
++ y == true, y + 1 != true. Of course, you would also want to be
able
to run the loop backwards to give true before false as the
philosophers
use. Change the initialization and test but not the increment.
bool a(true);
do {
something_with(a);
a = ! a;
} while (! a);
...
|
Well, if you consider it as a general pattern, it doesn't really run the
loop backwards. The results just happen to be the same for two-element
loops.
--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andrey Tarasevich Guest
|
Posted: Fri Jun 27, 2003 4:47 pm Post subject: Re: Using bool values as loop indexes |
|
|
John Potter wrote:
| Quote: | ...
Not really. A do-loop will work:
bool a = false;
do {
bool b = false;
do {
std::cout << a << " " << b << " " << a && !b << "n";
} while (b++ != true);
} while (a++ != true);
Sorry, there is no postfix increment/decrement for bool. Prefix is
valid but depricated.
...
|
Huh? There is no decrement for 'bool' (neither postfix nor prefix).
There are both postfix and prefix increments for 'bool', although both
forms are deprecated.
--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Sat Jun 28, 2003 11:05 pm Post subject: Re: Using bool values as loop indexes |
|
|
KIM Seungbeom wrote:
| Quote: |
For bools:
for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}
|
do_something(false);
do_something(true);
Much simpler.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Jun 29, 2003 12:34 pm Post subject: Re: Using bool values as loop indexes |
|
|
In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker <petebecker (AT) acm (DOT) org>
writes
| Quote: | KIM Seungbeom wrote:
For bools:
for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}
do_something(false);
do_something(true);
Much simpler.
|
True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.
--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andy Sawyer Guest
|
Posted: Mon Jun 30, 2003 9:13 am Post subject: Re: Using bool values as loop indexes |
|
|
In article <H2HJa.61589$Io.5776802 (AT) newsread2 (DOT) prod.itd.earthlink.net>,
on 23 Jun 2003 18:43:03 -0400,
"Matthew Seitz" <mseitz (AT) yahoo (DOT) com> wrote:
| Quote: | Is there a commonly accepted "best way" or idiom for using a bool value as a
loop index? I want to generate a boolean truth-table. Here is a simplified
version of my initial code:
for( bool a = false; a <= true; ++a){
for(bool b = false; b<=true; ++b){
std::cout << a << " " << b << " " << a && !b << std::endl;
}
}
Unfortunately, this leads to an infinite loop, because ++b still equals
true. I can see various ways to solve this problem. I was wondering what
is the most common or best solution to the problem.
|
How about something like:
class boolindex {
unsigned value_;
public:
boolindex() : value_(0) {}
boolindex operator++() { ++value_; }
operator bool() const { return value_; }
bool operator!() const { return !value_; }
bool valid() const { return value_ < 2; }
};
for( boolindex a ; a.valid() ; ++a )
for( boolindex b ; b.valid() ; ++b )
std::cout << a << ' ' << b ' ' << (a && !b) << std::endl;
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Mon Jun 30, 2003 9:21 am Post subject: Re: Using bool values as loop indexes |
|
|
On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
<francis.glassborow (AT) ntlworld (DOT) com> wrote:
| Quote: | In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
writes
do_something(false);
do_something(true);
Much simpler.
True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.
|
I just noticed that Pete has the optimal. Consider three levels.
do_something(false, false, false);
do_something(false, false, true);
do_something(false, true, false);
do_something(false, true, true);
do_something(true, false, false);
do_something(true, false, true);
do_something(true, true, false);
do_something(true, true, true);
Try loops.
bool a(false);
do {
bool b(false);
do {
bool c(false);
do {
do_something(a, b, c);
c = ! c;
} while (c);
b = ! b;
} while (b);
a = ! a;
} while (a);
Eventually the loops will be less statements than the repeated code.
Will it be interesting?
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Tue Jul 01, 2003 9:57 pm Post subject: Re: Using bool values as loop indexes |
|
|
Francis Glassborow wrote:
| Quote: |
In message <864r27ths7.fsf (AT) Zorthluthik (DOT) local.bar>, llewelly
[email]llewelly.at (AT) xmission (DOT) dot.com[/email]> writes
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
[email]francis.glassborow (AT) ntlworld (DOT) com[/email]> wrote:
In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
[email]petebecker (AT) acm (DOT) org[/email]
writes
do_something(false);
do_something(true);
Much simpler.
True, for a single level but rather different when you have
such
loops
nested three or four deep -- which was the OP's motivation.
At four deep Pete's style still wins, by one line, by my
calculations. At 5 deep the nested do-whiles win, but who wants
loops nested 5 deep?
But what it does not do is to express clearly in code the intent.
|
What could be clearer than enumerating all the desired cases?
| Quote: | It
also require a great deal of care to ensure that all cases have been
covered (and none repeated).
|
On the contrary: it's easy. Just count in binary.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
llewelly Guest
|
Posted: Wed Jul 02, 2003 1:00 am Post subject: Re: Using bool values as loop indexes |
|
|
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> writes:
| Quote: | In message <864r27ths7.fsf (AT) Zorthluthik (DOT) local.bar>, llewelly
[email]llewelly.at (AT) xmission (DOT) dot.com[/email]> writes
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
On 29 Jun 2003 08:34:36 -0400, Francis Glassborow
[email]francis.glassborow (AT) ntlworld (DOT) com[/email]> wrote:
In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
[email]petebecker (AT) acm (DOT) org[/email]
writes
do_something(false);
do_something(true);
Much simpler.
True, for a single level but rather different when you have such
loops
nested three or four deep -- which was the OP's motivation.
At four deep Pete's style still wins, by one line, by my
calculations. At 5 deep the nested do-whiles win, but who wants
loops nested 5 deep?
But what it does not do is to express clearly in code the intent.
|
I think I agree with you, but I am not sure which it you are referring
to. I do not think either Pete's linear example or John's
nested do-while loops express clearly in code the intent for any
number of levels greater than 2. The do-while with bool is IMO
uncommonly seen, and if they are nested three or more deep I think
most of the people I have worked with would be completely
mystified.
| Quote: |
It also require a great deal of care to ensure that all cases have been
covered (and none repeated). LoC is not a very good measure of clarity.
|
I thought we were playing a game with line counts. I would say LoC is
not a measure of clarity at all; note that my example has several
more lines than necessary, for reasons of clarity. I am sorry, but
I cannot take discussions about line counts seriously; the fact
that we teach each other to measure our code by an illusion that
has nothing to do with functionality, has no clear relation to
readibility or complexity, is somewhere between disturbing and
ridiculous.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Wed Jul 02, 2003 2:52 am Post subject: Re: Using bool values as loop indexes |
|
|
Francis Glassborow <francis.glassborow (AT) ntlworld (DOT) com> wrote
| Quote: | In message <3EFCD510.702B2062 (AT) acm (DOT) org>, Pete Becker
writes
KIM Seungbeom wrote:
For bools:
for (bool b = false; /* b <= true */; b = !b) {
// do something
if (b == true) break;
}
do_something(false);
do_something(true);
Much simpler.
True, for a single level but rather different when you have such loops
nested three or four deep -- which was the OP's motivation.
|
Three levels of bools are a very obfuscated way to count from 0 to 7.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|