> I came across the following code today (actually its from CppTest): > > void TestSuite::run (TestResult *result) > { > for (std::vector<Test *>::iterator it = m_tests.begin (); > it != m_tests.end (); > ++it) { > // loop code > } > } Here's mine. // This should be in the TestSuite header file. // typedef std::vector<Test *> TestVecPtr; typedef TestVecPtr::const_iterator TestVecIter; // This should be in the class definition. // TestVecPtr m_tests; // Iterate through a collection of Test base objects, performing // the test on each item. Return the agregate test result when done // via TestResult. void TestSuite::run(TestResult &test_result) { TestVecIter tv_iter, tv_end(m_tests.end()); for(tv_iter = m_tests.begin(); tv_iter != tv_end; ++tv_iter) { // loop code, setting test_result to some value. } } > In this example, I would do: > > typedef std::vector<Test *>::iterator TestIterator; Agreed. I would also typedef the iterators for this std::vector. See above. > Another thing is that iterators are pretty common, so I think having a > standard macro for traversing with one would be very useful. Here's my > suggestion: > > #define foreach(elem,set) for (elem = set.begin (); elem != set.end (); > ++elem) > > Oh, I know, I can hear the groaning out there... "we don't use #define > macros -- that's old-style, icky C crap that we sophisticated C++ > programmers don't use". Maybe, but I still think macros are extremely > useful when used sparingly and judiciously. They're awfully good at > hiding uglies. The reason that #defines are not used is that they introduce non-type-save constants that C++ can not catch when improperly used. Defines also (as in this case) introduce class functions and stand-alone functions that can be better implemented using standard function notation. A classic case in point are the definitions of min() and max() where in one case they're #defined and unsafe and the other they're implemented via templates. If your code is so ugly that it needs to hide behind a #define, then maybe the code should be re-written. To finish the argument, there is already a for_each() function implemented. It takes three arguments; the container start, the container end, and a function to execute on behalf of each element in the container. > Now using those two code snippets above, I can rewrite the example > (using OpenTracker formatting) as follows: > > void > TestSuite::run (TestResult *result) > { > TestIterator i; > foreach (i, m_tests) { > // loop code > } > } The problem with that example is the programmer's desire to use one-letter variables. Using one-letter variables looks great in a text on programming but are the bane of software maintenance. Go looking for one-letter variables (at 3 am in the morning before a large code drop/demo after 14 hours of debugging an intermitent bug) in a large body of code, especially if you use any of the vowels. Other points: 1 / Use const where ever possible, such as const arguments or const iterators. 2 / Pass by const rather than pointer, and if you must pass by pointer, pass by const pointer or pointer to const ref. 3 / Keep lines as short as possible. Don't run on. Since people have been writing they've been writing in a format with allows multiple columns on a page. It's because it's easier for humans to read. You can't have multiple columns in source code (not yet, anyway), but you can have readability. For example, in declairing variables: void MyFunc(const std::string &str) { std::string work_str, str_token, another_str; int count, foo, bar ... } 3 / Use indentation and whitespace to promote readability. Python lives by this. So should all other languages. 4 / For the sake of those you work with please use a little verbosity in your coding. 5 / For the sake of those you work with please use comments, especially a block at the start of each class function or function. We'd like to know what you're trying to do, especially if we've never seen the code before. This goes hand-in-hand with point 4 above. 6 / Use namespaces. Use the ones that already exist (such as std) and create new ones to avoid collisions in new code. If I sound overly critical, I'm not. I'm in violent agreement with your goals. You're moving in the right direction, and it's a lot better than quite a bit of open-source (and closed-source) code I've seen. Also, please look at http://www.camtp.uni-mb.si/books/Thinking-in-C++/Contents.html, as it covers C++ with lots of examples.