Out of the loop
for (int i = 0; i < ARRAY_SIZE; i++) { // do something to an array...You should be ashamed of yourself. That code is a crime against modern C++. Come out with something like that down the ACCU, you could find yourself sentenced to six months mentoring Linus Torvalds through his Visual Basic breakdown.
Out of the (C++) loop - The Register
That article is one of the best descriptions of troubles with the STL I've read. When I use the STL, things seems far more complicated then they should be, the code becomes more verbose and I feel like the actual meaning and intents are obscured, which is ironic because it's suppose to have the opposite effect.
Look at how much typing you have to do just to declare an simple iterator:
std::map<std::string, FoobarClass>::const_iterator itor;
And how exactly is this supposed to be better?
But when I don't use the STL, I feel like I'm doing something wrong somehow because I'm not enjoying benefits of meta programming and templates. Clearly there is something wrong with me.
The way I've heard it, using the STL is supposed to save you all sorts of time while making your code rock solid, whitening your teeth and improving how your odor is perceived by the opposite sex. But all I get is a smug satisfaction that I was at least smart enough to get it to compile and run, and that only lasts about ten minutes. Then the next time I see the code I'm horrified how ugly it looks and I curse myself for picking the STL in the first place.
If only I were somehow smart enough to enjoy all it's great benefits, but apparently I am too dim to find it productive beyond simple containers.
Posted September 25, 2006 2:09 PM
Comments
Simple containers are a huge win. I faint when I imagine all the C code I'd have to write just to accomplish this:
struct Contact
{
string name;
vector addresses;
int age;
};
vector contacts;
Contact myContact;
contacts.insert(contacts.begin() + 5, myContact);
But I think you're talking more about the "advanced" capabilities of the STL, which involve functors and algorithms and, for the most part, I can give them a miss. Iterators don't scare me much (if you really think the syntax is bad, typedef it away so you only have to write the ugliness once). But I still would rather write a loop rather than call foreach.
Alyosha`, September 25, 2006 3:24 PM
Hey, I'm with you, I use vector and map all the time, they are useful and save time. Well, compared to hand-writing your own containers.
The typedef works fine for a commonly used container class, but for those one-off usages of a container it just becomes another layer of indirection and noise.
Something jumped out at me in your example:
zoomed closer:
GAHHHHH!!! What is that?!? Actually, I know exactly what that is, and I still remember how it looked the first time I saw it because I vomit a little bit in the back of my throat every time I see it again. It that weird iterator madness where you can just add numbers, positive and negative, and it works because they are like psuedo pointers, but not really (except that they are and they have many of the same problems as pointers). And indeed it's all done this way to be compatiple with C pointer arithmetic, so that they too can be plugged into the same "generic" algorithms.
Anyway sorry for the mini rant, I'm actually agreeing with you, the STL containers are a good thing. But only because they are better than nothing at all. The problem is they are designed to work in some grand generic algorithm/meta programming universe that nobody can quite get their heads completely around. If instead they were just designed to be simple and pragmatic, they'd be far more useful in the common case.
Damien, September 25, 2006 3:55 PM
So was the "i++" intentionally left out?
I love the new Java 5 For..Each loop:
void cancelAll(Collection<TimerTask> c) {
for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); )
i.next().cancel();
}
Bob Balfe, September 25, 2006 5:09 PM
No, something swallowed the pluses in the original posting. Thanks for the heads up, I've added them back.
Damien, September 25, 2006 5:14 PM
Yeah, specifically in the case of vector::insert, I wish I could just pass in 5 and have it understood as begin() + 5. That would have gone a long way with usability.
But I made my peace with iterators a long time ago. I think they're pretty slick, really they're no more than a generalization of the concept of a pointer. Vector iterators are either bare pointers, or classes that look JUST LIKE pointers but do additional debug validation. And list iterators are classes that again, look JUST LIKE pointers but have special magic so that ++it follows through the pNode->pNext pointer. If you can get over the whole "operator overloading is an abomination unto the LORD" mindset, and just relax and accept it, it is pretty elegant way of expressing the underly basic concept of "go to the next item".
But okay, as far as algorithms go, sure I understand that if I just invoke a function the compiler has the ability to outline it (or inline it). But that's really a micro-optimization, and one that comes at the sake of readability. Other than that I can see no real reason to use algorithms. (Well, except for maybe std::sort; that one has a special place in my heart). But stuff like bind2nd ... if I ever have to use it again in my life, it'll be too soon ...
Alyosha`, September 25, 2006 5:23 PM
I agree that highly generic templates can add a lot of unnecessary noise to code (or a lot of unneccessary typedefs) but it's really the fault of C++ for not supporting either:
for (typeof(foo)::iterator it = foo.begin(); ...
or even better,
for (foo::iterator it = foo.begin(); ...
There's no actual reason for this syntax not being supported in C++, it just isn't :(
markp, September 25, 2006 6:52 PM
Dude, STL coding is sooo nineties...
You really should have taken up modern languages by now:
foreach ($obj as $val) { ... }
there you have it: clean, concise and understandable. works on objects, arrays and hash maps alike.
Jokes aside, I really am sorry of the tons of cruft and boilerplate code that coders have to endure daily because of the limitations of the platform they have to use. Luckily we have better tools today, and that includes languages, too.
A little precious gem of coding wisdom I stumbled upon recently read something like: "many coders are fond of design patterns, but every widely-used design pattern is in fact a deficiency of the language itself". Makes a lot more sense when you realize subroutines where 'design patterns' too, in a not-too-distant past...
Gaetano Giunta, September 26, 2006 4:12 AM
container.each do |element|
stuff
end
Matt, September 26, 2006 5:14 PM
Sigh! Woe is me. I see nothing wrong with the original code (I use stuff like that all over the place), don't even know what STL is, and yet I have over a 1,100,000 licensed users of my software, customers in 46 countries and do business with 7 out of 10 of the largest companies in the world, along with the governments of at least ten countries. Imagine what I will accomplish if I ever learn modern programming!
Ben Langhinrichs, October 7, 2006 11:13 PM
The container.each do |a| ... end is Ruby code, although for a in container ... end also works in Ruby. Python uses indentation to lose a few characters:
The point is that it's really hard to think in statically typed languages like the "industrial" languages C, C++, Java, C#, etc. Ideally one would use a dynamically typed language with optional static type declarations for speed and ability to think, but the only language I'm aware of that can do this is Lisp. Are there others?
Connelly Barnes, October 11, 2006 9:00 PM
Post a comment