Stupid C++ Template Tricks: Conway's Game of Life
blog.mattbierner.com
blog.mattbierner.com
The fact that this is possible, during compile time, is cause for open weeping.
EDIT:
Note that this was not done in an ugly or even unreasonable way: the author clearly wrote code that is easy to follow, well-structured, and not abusing language features in any way. This is not a good thing.
EDIT: Note that I am not endorsing C++ or doing crazy things with templates. I tend to like C++ personally, but have also been finding the simplicity of C to be quite nice, and have worked with a decent number of other languages (popular and academic, with varying degrees of time spent from professional to a small side project). I'm merely curious about why using the template system to calculate things (even if they're large, complicated things) is immediately declared as "bad" if the code is well-written, rather than something that requires 6 months of study to really understand.
And even then, it's important to recognize that bloat is a relative measure. If you use just one instantiation of a template, you're not paying for multiple versions of the code.
If, on the other hand, you use multiple instantiations, the code will be bloated compared to, say, a single type-erased version— but will not be any bigger than if you had written several "instantiations" of the same code by hand. There's a tradeoff to be made, too, since a statically-typed version of a function will probably be faster than a type-erased version.
Anyway, w.r.t. bloat, templates aren't the problem; static polymorphism is (can be). Templates are just a way of implementing static polymorphism.
I wrote template headers in such a way that they could be included into a common .cc file, where template instantiations could be placed. By defining some #define symbol prior to including a template header, I would force it to supply the definitions. Without the #define, no other translation unit had access to the template bodies, and so generating bloat couldn't happen. (Another way is to have two headers: foo.h for the template declaration and foo-impl.h for the bodies of the template functions: foo-impl.h is only included in the translation unit that instantiates.)
If the templates for different types are instantiated in the same translation unit, that maximizes the opportunity that the code for identical expansions can be merged (if the compiler supports it). But more importantly, you control the bloat through the discipline of having a catalog of explicit expansions.
I avoided code bloat not only by using the above trick, but simply by writing light-weight templates. Templates cause particular bloat when they are inlined, because inline functions cause bloat, and inline templates generate them. The solution: don't put anything into the body of a template function that you wouldn't put into an inline function. Secondly, make the tiny inline template function rely only on non-template pieces to do its job. Sometimes designing this way creates a type-fragile implementation. However, if that code is used properly through the templates (and only through the templates), then it is safe.
Perhaps C++ compilers handle templates better now in the sense of managing the expansion more transparently and merging some of the bloat; but manual techniques have worked well for a long time.
However, that I can do without, doesn't mean that this is "not a good thing" to have as part of the language. The flexibility of C++, including what comes with the help of the preprocessor and meta-programming is part of what powers many of the features you use. Even if you yourself are not using those features, you are relying on libraries that do.
Even if your use case somehow didn't need this or anything that comes as a result, most use cases do. Which makes a good enough reason for it to be an excellent feature of the language.
This is a good thing.
There are people that use templates to their full ability, and do not bat an eye at the resulting template errors or weird code issues.
Most of the times I see people using templates I can't help but wonder "Why the heck aren't you using a language that fits your problem better?".
They're cool features, sure, but notice that the days of C++ as a practical get-shit-done language are pretty much over. There's not really anything I'd consider C++ best or even second-best at if you can use other languages.
If you belong to either of 1) or 2), it doesn't matter whether or not this feature is possible, you can choose not to use the libraries, and you can choose not to use meta-programming features.
Could you share an argument as to why you feel a language shouldn't have features that you don't have to use?
If you don't use STL, boost, QT, or pretty much any C++ library I can think of... do you write everything from scratch?
As for when C++ is "best" or "second-best", these kind of questions tend to lead to opinion-based arguing, rather than constructive discussion. I'm definitely not interest in the former, so I'll just give you the general objective consensus of the programming world: C and C++ are used when performance matters. C++ allows more abstraction without a real runtime cost.
A good read: http://programmers.stackexchange.com/questions/29109/is-ther...
The problem is that the vast majority of languages have some features that you don't use, and even if others use them then things still generally work out okay--you can hide it away.
C++, via operator overloading, exceptions, backwards compatibility with C and its problems, templates, function overloading, and all manner of other things, is simply too large to be trusted. I assert that it is so difficult as to be practically impossible to ensure that, if you rely on third-party code outside of your direct control or the language spec, you are writing safe, performant, bug-free, and maintainable C++ code. C is magnitudes simpler, and people still manage to fuck that up.
Everyone bandies about the performance of C++ and the whole only-pay-for-what-you-use aspects of it, but in the fast majority of cases that's simply not important from a business or project standpoint. If you're writing numerical code, for example, why not just use the hyper-optimized compilers available for Fortran? If you're writing tight embedded control code, why not just use assembly?
Sure, I've had a friend that worked on the CMS at Cern and they used some unholy pile of C++ dating back 20 years and that worked well. I've known a bunch of people doing bioinformatics and they all write/copy/paste shitty C++ and get faster results than their semi-legible Python or MATLAB.
That said, all of those use cases are academic, which is maybe the last place where performance even matters (arguable in and of itself). You might claim "but but but games!" and then you'd be wrong again, because a great number of games are written using super-slow scripting engines and terrible C++ codebases. Mike Acton, giving a talk at a conference this year, pointed out that there was no compelling reason to use C++ over C because the OOP features fall on their face in a high-performance environment.
It's just a bad language. It was useful once, it's occasionally useful now (if you must, which you usually don't), but we really should just move on to new things.
Its OOP features are poorly thought-out, its performance with the standard library is pretty bad without modification for certain use cases, its learning curve is absurd, its growth is unbounded. Just let the thing die.
To answer your question about rewriting things:
We did write a lot of things from scratch, and spent years battle-hardening them, because we didn't want to deal with the (at that time horrid) development overhead and philosophical issues of Boost. STL was fine until it wasn't due to some cross-platform issues. QT/POCO are cool in their own right, but didn't match our use case.
Took me a while to compile (gcc 4.8.3 on cygwin64, had to add -std=c++11 -fpermissive)
I don't mean c++ isn't hard, I'm just saying it's not the only language where small typos can make everything explode.