Re: Variables in for loop (style issue)
Maciej Sobczak wrote:
Consider this:
for (size_t i = 0; i != v.size(); ++i)
{
// do something with v[i]
}
The above is considered to be a bad practice...
[snip]
Yes, it certainly is. I've seen it often enough to recognize what
it's trying to accomplish (even sometimes in textbooks written
by so-called experts!), but it's both ugly and inefficient.
Loops should always take at least 26 lines (including at least
5 blank lines), which is probably why so many textbooks try
to compress them (to save on paper). But this is really the
ONLY way that loops should ever be written, according to the
coding standards of several places that I've worked:
{ // Start of loop
// Values for indexes (just in case it's needed)
// Note: these optimize away if not needed!
const size_t firstindex=0;
const int firstindex_as_int
= static_cast<int>(firstindex);
const size_t lastindex=v.size()-1;
const int lastindex_as_int
= static_cast<int>(lastindex);
// Values for iterators (always needed)
const itertype firstiter = v.begin();
const itertype lastiter = v.end();
// The loop itself
int currindex=firstindex_as_int;
for (itertype curriter = firstiter;
currindex!=(lastindex_as_int+1)
&& curriter!=lastiter;
++curriter, ++currindex)
{
// do something with v[currindex] and/or *curriter
}
} // End of loop
With a suitable typedefs for itertype, of course.
The comments are mandatory and must not be changed.
The names of the other variables (except v of course) shouldn't
change either, unless you're nesting loops and need to access
the names of the variables from the outer loop inside the inner
loop, in which case you would prepend loop1_ or loop2_ (or
so on) to the variable names.
Depending on when and where you learned C++, this could be
a shock the very first time you see it... but once you see it
often enough (a few thousand times), it gets extremely easy to
recognize the pattern and know what's happening.
Here's a complete example program that initializes a
vector and then displays the results on the console:
#include <vector>
#include <iostream>
// These (and more) would actually be in a common
// #include file, included in every module
// (with precompiled headers, of course)
#define asize(a) (sizeof(a)/sizeof(a[0]))
typedef std::vector<int> intvec;
typedef std::vector<int>::iterator intvec_iter;
const char newline = '\n';
// Constants for cout
const char colen_space[] = "*: ";
// Constants for vectors
int vector_values[] = { 10, 40, 20, 50, 30, 60,
15, 45, 25, 55, 35, 65 };
int main() {
// Create and initialize a vector of int
intvec v(vector_values,
vector_values+asize(vector_values));
// Here's the example of the loop!
{ // Start of loop
// Values for indexes (just in case it's needed)
// Note: these optimize away if not needed!
const size_t firstindex=0;
const int firstindex_as_int
= static_cast<int>(firstindex);
const size_t lastindex=v.size()-1;
const int lastindex_as_int
= static_cast<int>(lastindex);
// Values for iterators (always needed)
const intvec_iter firstiter = v.begin();
const intvec_iter lastiter = v.end();
// The loop itself
int currindex=firstindex_as_int;
for (intvec_iter curriter = firstiter;
currindex!=(lastindex_as_int+1)
&& curriter!=lastiter;
++curriter, ++currindex)
{
// Note that for any integer x,
// (x*1+0) optimizes to just x.
std::cout << (currindex*1+0)
<< &colen_space[currindex*0+1]
<< (*curriter*1+0)
<< static_cast<char>(newline);
}
} // End of loop
std::cout << "Fin" << std::endl;
}
Honestly, what other technique could possibly be easier to read
(once you've been exposed to it) or more efficient to execute?
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]