tags:

views:

1850

answers:

15

I discovered template metaprogramming more than 5 years ago and got a huge kick out of reading Modern C++ Design but I never found an opertunity to use it in real life.

Have you ever used this technique in real code?

Contributors to Boost need not apply ;o)

+8  A: 

I've used it in the inner loops of a game's graphics code, where you want some level of abstraction and modularity but can't pay the cost of branches or virtual calls. Overall it was a better solution than a proliferation of handwritten special-case functions.

+11  A: 

I once used template metaprogramming in C++ to implement a technique called "symbolic perturbation" for dealing with degenerate input in geometric algorithms. By representing arithmetic expressions as nested templates (i.e. basically by writing out the parse trees by hand) I was able to hand off all the expression analysis to the template processor.

Doing this kind of thing with templates is more efficient than, say, writing expression trees using objects and doing the analysis at runtime. It's faster because the modified (perturbed) expression tree is then available to the optimizer at the same level as the rest of your code, so you get the full benefits of optimization, both within your expressions but also (where possible) between your expressions and the surrounding code.

Of course you could accomplish the same thing by implementing a small DSL (domain specific language) for your expressions and the pasting the translated C++ code into your regular program. That would get you all the same optimization benefits and also be more legible -- but the tradeoff is that you have to maintain a parser.

Eric
A: 

I write System Programs and I use Templates Heavily, It Provides a Lot Comfort

Why all the capitalization, foo'?
Jonathan Sterling
+1  A: 

Yes I have, mostly to do some things that resemble duck-typing when I was wrapping a legacy API in a more modern C++ interface.

Leon Timmermans
+1  A: 

No I haven't used it in production code.

Why?

  1. We have to support 6+ platforms with native platform compilers. It's hard enough to use STL in this environment let alone modern template techniques.
  2. Developers don't seem to be keeping up C++ advances anymore. We use C++ when we have to. We have legacy code with legacy designs. New code is done in something else e.g., Java, Javascript, Flash.
maccullt
Sadly this is the case for us too.
Motti
A: 

Many programmers don't use templates much because of the poor compiler support up until recently. However, while templates have had a lot of issues in the pas, newer compilers have much better support. I write code that has to work with GCC on Mac and Linux as well as Microsoft Visual C++ and it's only with GCC 4 and VC++ 2005 that these compiler have supported the standard really well.

Generic programming via templates is not something you need all the time but is definitely a useful code to have in your toolbox.

The obvious example container classes but templates are also useful for many other things. Two examples from my own work are:

  • Smart pointers ( e.g. Reference-counted, copy-on-write, etc.)
  • Math support classes such as Matrices, vectors, splines, etc. that need to support a variety of data types and still be efficient.
Calliphony
The question was about template *meta*programming, not plain old templates which are much more commonly used.
Motti
+5  A: 

Template metaprogramming and expression templates are becoming more popular in the scientific community as optimization methods that offload some of the computational effort onto the compiler while maintaining some abstraction. The resulting code is larger and less readable, but I have used these techniques to speed up linear algebra libraries and quadrature methods in FEM libraries.

For application-specific reading, Todd Veldhuizen is a big name in this area. A popular book is C++ and Object Oriented Numeric Computing for Scientists and Engineers by Daoqi Yang.

Jared A Hicks
Well, according to the table of contents, D. Yang's book contains 7 pages of material on expr. templates and template metaprogramming. The rest seems to be a general programming 101 textbook, with a few example with numerical methods. Nothing wrong with that, of course.
janneb
Fair enough. For a more complete reference, I would go with the Alexandrescu book. The references I cited were specific to scientific computing applications, and may be limited by my knowledge of the literature. The [Barton/Nackman](http://www.amazon.com/Scientific-Engineering-Introduction-Advanced-Techniques/dp/0201533936) book also has a small amount of material.
Jared A Hicks
+4  A: 

Most programmers who use template metaprogramming use it indirectly, through libraries like boost. They don't even probably know what is happening behind the scenes, only that it makes the syntax of certain operations much much easier.

+1  A: 

Don't do that. The reason behind that is as follows: by nature of template metaprogramming, if some part of your logic is done at compile-time, every logic that it is dependent on must be done at compile time as well. Once you start it, do one portion of your logic at compile time, there is no return. The snowball will keep on rolling and there is no way to stop it.

For example, you can't iterate on the elements of a boost::tuple<>, because you can only access them at compile time. You must use template metaprogramming to achieve what would have been easy and straightforward C++, and this always happens when the users of C++ aren't careful enough not to move too many things to compile-time. Sometimes it is difficult to see when a certain use of compiletime logic would become problematic, and sometimes programmers are eager to try and test what they've read in Alexandrescu's. In any case, this is a very bad idea in my opinion.

mpl::for_each, boost.fusion, clever cons<car,cdr> specialization all allow fairly easy bridging from compile to run-time v
KitsuneYMG
+5  A: 

I use template metaprogramming all the time, but in D, not C++. C++'s template metalanguage was originally designed for simple type parametrization and became a Turing complete metalanguage almost by accident. It is therefore a Turing tarpit that only Andrei Alexandrescu, not mere mortals, can use.

D's template sublangauge, on the other hand, was actually designed for metaprogramming beyond simple type parametrization. Andrei Alexandrescu seems to love it, but other people can actually understand his D templates. It's also powerful enough that someone wrote a compile-time raytracer in it as a proof of concept.

I guess the most useful/non-trivial metaprogram I ever wrote in D was a function template that, given a struct type as the template parameter and a list of column header names in an order corresponding to the variable declarations in the struct as a runtime parameter, will read in a CSV file, and return an array of structs, one for each row, with each struct field corresponding to a column. All type conversions (string to float, int, etc.) are done automatically, based on the types of the template fields.

Another good one, which mostly works, but still doesn't handle a few cases properly, is a deep copy function template that handles structs, classes, and arrays properly. It uses only compile time reflection/introspection, so that it can work with structs, which, unlike full-blown classes, have no runtime reflection/introspection capabiities in D because they're supposed to be lightweight.

It's useful to know about D, but I think the question is about C++, not D.
Neil Mayhew
Regardless, it's useful to know what kinds of things you can accomplish with metaprogramming when you don't have to be a guru to understand it :)
shambulator
+6  A: 

I've found policies, described in Modern C++ Design, really useful in two situations:

  1. When I'm developing a component that I expect will be reused, but in a slightly different way. Alexandrescu's suggestion of using a policy to reflect a design fits in really well here - it helps me get past questions like, "I could do this with a background thread, but what if someone later on wants to do it in time slices?" Ok fine, I just write my class to accept a ConcurrencyPolicy and implement the one I need at the moment. Then at least I know the person who comes behind me can write and plug in a new policy when they need it, without having to totally rework my design.

  2. When I'm trying to refactor several similar blocks of code into one. Usually the code will be copy-pasted and modified slightly because it would have had too much if/else logic otherwise, or because the types involved were too different. I've found that policies often allow for a clean one-fits-all version where traditional logic or multiple inheritance would not.

Nathan Monteleone
+1  A: 

Almost 8 months after asking this I've finally used some TMP, I use a TypeList of interfaces in order to implement QueryInterface in a base class.

Motti
I have wanted to do the same thing but didn't get around to it yet. We have a lot of legacy code wrapped as COM objects so it can be accessed from C#, but no-one wants to work on it or extend it because the COM boilerplate is so tedious. I feel sure template metaprogramming could really help, but simple template programming isn't up to it because of the way COM rules differ from C++ ones.
Neil Mayhew
+2  A: 

I use it with boost::statechart for large statemachines.

KitsuneYMG
You should try the upcoming boost:msm - the meta state machine (hopefully in boost 2.0). It's an entrire state machine framework based on metaprogramming. And its UML2 compliant. We did use it for a few projects and its just awesome. Well, on the downside, there a long compilation times...
fmuecke
So how does it differ in features from sc? The only uml concepts sc lack are spilt and join, which are easy to emulate.
KitsuneYMG
@fmuecke Just an update. I looked at msm now that it's in boost proper. It is in no way a replacement for statechart as it seems to lack any type of hierarchy. MSM looks to be a state transition diagram where statechart is more like a statechart from stateflow/simulink.
KitsuneYMG
+1  A: 

I've used it quite a bit with DSP code, especially FFTs, fixed size circular buffers, hadamard transforms and the like.

carleeto
+2  A: 

Template meta programming is a wonderful and power technique when writing c++ libraries. I've used it a few time in custom solutions, but usually a less elegant old style c++ solution is easier to get through code review and easier to maintain for other users.

However, I've got a lot of mileage out of template meta programming when writing reusable components/libraries. I'm not talking anything as large some of Boost's stuff just smallish components that will be reused frequently.

I used TMP for a singleton system where the user could specify what type of singleton they desired. The interface was very basic. Underneath it was powered by heavy TMP.

template< typename T >
T& singleton();

template< typename T >
T& zombie_singleton();

template< typename T >
T& phoenix_singleton();

Another successful use was simplifying our IPC layer. It is built using classic OO style. Each message needs to derive from an abstract base class and override some serialization methods. Nothing too extreme, but it generates a lot of boiler plate code.

We threw some TMP at it and automated the generation of all the code for the simple case of messages containing only POD data. The TMP messages still used the OO backend but they massively reduce the amount of boiler plate code. The TMP was also used to generate the message vistor. Over time all our message migrated to the TMP method. It was easier and less code to build a simple POD struct just for message passing and add the few (maybe 3) lines needed to get the TMP to generate the classes than it was to derive a new message to send a regular class across the IPC framework.

caspin