I just learned about template parameters today. Now, you (dear reader) probably fall into one of the following categories:
- “What’s a template parameter?” or
- “Duh, what took you so long?” or
- “…and you haven’t slit your wrists?”
If you are dazed and confused at the following, count your lucky stars, you might be in the position of understanding it.
When I wasn’t looking (I was off at a couple startups for a few years, first doing Java, then doing embedded stuff in C) they went and changed C++ from a horribly complex and convoluted (but logically consistent … if you remember to step on the yellow flowers and not get sucked into the swamp) object-oriented programming language … er, they changed C++ to a horribly complex and complicated object-oriented programming language with an unbelievably nasty and arcane type-based macro system called templates. Templates were gnarly when I looked at ’em six or seven years ago, and like all things that get entangled in C++, they haven’t gotten better.
That sucking sound you heard was me missing one of the yellow flowers and getting pulled down into the mud. At least it’s nice and peaceful here; I can still hear the screaming of those poor souls who are trying to cross the swamp. Did you hear that “Ouch!”? What’s the difference between GCC and Visual C++? (Ans: Neither one is very good at templates). Ouch. Why does Koenig lookup suck so bad? (Ans: Because we need it). Dealing with templates and writing stable libraries that provide (or use) templates is a huge mother of a stinking, sucking swamp. And if you don’t believe me, look up two-phase lookup and (after you’re done screaming) pay me $10.
Template parameters, oh yeah. I’m not going to get into grody details too much. First you define a nice innocent little template class, then you inject it into another template as a parameter using an icky syntax that kind of fell out of someone’s bad experience with Perl, causing the victim to inherit from that first template in a really disturbingly intimate way. (It’s called a policy in this context). You have put one body of code at the direct mercy of another body of code, and now you can turn the screws until they sing soprano in harmony. Turing-equivalent, sentient macros anyone? Two hundred megabyte working sets to compile “Hello, world!”? It’s all coming.
This is all great, heady stuff, but it violates principle #2 of developing a programming language, namely, “Thou Shalt Have a Debugger From Day One (You’ll Need One Anyway).” I can easily see folks pouring over pages of dumped internal compiler symbols, searching for lost scopes and violated commas. In Days of Yore you could give your average IBM 360 programmer a foot-thick core dump and he’d go FlipFlipFlipFlip-thinkThink-Flip and (all in twenty five seconds) stab his index finger at the offending byte in a sea of hexadecimal. Like that, only with angle brackets and about a zillion lookup rules and namespaces sprouting off in all directions. Ka-boom.
It’s been said that one of the best competitive advantages you can have is a technology that your opponent doesn’t understand the value of. This does even better than that, a technology that actively causes your opponent’s head to vibrate and explode. Ka-boom. It’s even funnier when the compiler truncates error messages to 255 characters and you have to guess at the rest or rename stuff so that the diagnostics fit [or — heh — patch the compiler]. Getting a clean compile is like playing Twenty Questions with a pathological liar. God, I love this business.
So: Remember to stick spaces between your greater-than signs, to meditate on the reason why you don’t have to stick spaces between your less-than signs, and to thank Barney, from whose forehead all job security springs.
And I thought the whole idea was to get rid of that bad, evil #define. Silly me.