C++ Meta Templates: A Good or Bad Design Choice? - c++

I'm curious to find out if and when C++ meta templates are a good design choice for systems small to large. I understand that they increase your build time in order to speed up your execution time. However, I've heard that the meta template code is inherently hard to understand by many developers, which could be a problem for a large group of people working on a system with a very large code base (millions of lines of code). Where do you think C++ meta templates are useful (or not)?

Metaprogramming is just another tool in a (C++) programmers' toolbox - it has many great applications, but like anything can be mis- or over- used. I think it's got a bad reputation in terms of 'hard to use', and I think this mainly comes from the fact that it's a significant addition to the language and so takes a while to learn.
As an example of real-world use; I've used template metaprogramming to implement Compile-time asserts and shim libraries in the past; implementing these without templates would either have been impossible or required significantly more code than I had to write.
In the case of the shim library it could have been implemented in a classic object-orientated fashion which could have been designed to have a similar (low) level of code duplication as the templated implementation; however it's runtime performance would have been significantly worse.
If you want to see some good examples of how it can be used, I suggest you read Modern C++ Design by Andrei Alexandrescu (there is a sample chapter on the publisher's website) - IMO this is one of the best books on the subject.

Template metaprogramming doesn't make your code "inherently hard to understand". It moves the complexity around. The underlying metaprogramming code may be a pain to understand, but at the same time, it typically simplifies client code.
If its effect was just to make code harder to read, it wouldn't be used. The reason it is used from time to time is exactly that it simplifies the code as a whole.
Of course, programmers who are not familiar with metaprogramming will have trouble reading or maintaining the code, but isn't that just an argument against working with programmers who don't know their stuff?
Programmers who don't know about a for-loop wil find that hard to read too.

Fairly simple meta-programming is used throughout the standard library, in the form of traits. The standard library seems to be pretty well received, so I think we can say that meta programming is useful there.

I did face a situation where I had to tackle a not-so-big system which heavily used template metaprogramming (specifically static polymorphismus, SFINAE and maybe other techniques). And I can tell you that this will make it harder for the developers. If template metaprogramming is used a lot, every developer must be familiar with the techniques otherwise they won't be able to work productively.
On the other hand, some uses of templates are quite easy to understand and use. For example generic containers (vector), smart pointers, ...

As always, you need to balance the pros and the cons. If performance is your concern (there are other uses for template metaprogramming too), you should first demonstrate that there are significant and important performance gains to be had by using template metaprogramming techniques. (It's even quite possible to make a program that runs slower by hindering the compiler with excessive use of templates, so always measure!)
C++ templates were not originally designed for metaprogramming so even relatively simple problems solved with metaprogramming can produce code that is difficult to understand, especially to people who are not familiar with common template metaprogramming techniques (since they are usually not very intutitive). Also depending on your particular problem you might consider code generation vs. template metaprogramming.

This depends on who you're working with, and what they like and are familiar with. In the absence of any information I'd suggest the following concrete list of uncontroversial (and not very meta...) template 'things' for a new project:
handwritten smart pointers for whatever sorts of things your app uses
STL containers
static assert
And, for advanced users only:
traits used for some obvious standard application (script language bindings and serialization spring to mind)
This is perhaps a bit conservative but it seems to be easy to convince everybody of the value of these things. If well put together, they don't bloat compile times and mostly work pretty well with commonly-found code browsing facilities. And most of the templates shouldn't take much explaining, even to that large subset of C++ programmers who don't really understand templates all that well.
(Regarding boost, and any other template libraries that it has yet to merge with, it seems to be pretty adventurous by the standards of many (most?) C++ programmers at the moment. So it seems to me prudent to avoid it for now.)

Related

Heavy use of templates for mobile platforms

I've been flicking through the book Modern C++ Design by Andrei Alexandrescu and it seems interesting stuff. However it makes very extensive use of templates and I would like to find out if this should be avoided if using C++ for mobile platform development (Brew MP, WebOS, iOS etc.) due to size considerations.
In Symbian OS C++ the standard use of templates is discouraged, the Symbian OS itself uses them but using an idiom known as thin templates where the underlying implementation is done in a C style using void* pointers with a thin template layered on top of this to achieve type safety.
The reason they use this idiom as opposed to regular use of templates is specifically to avoid code bloating.
So what are opinions (or facts) on the use of templates when developing applications for mobile platforms.
Go ahead and use templates wherever they make your code easier to understand and to maintain. Avoidance of templates on mobile platforms can be categorized as "premature optimization".
If you run into executable-size issues, then redesign if necessary, but don't start with the assumption that templates will cause problems before you see any actual problems.
A lot of the stuff in "Modern C++ Design" and similar books is not going to lead to bloated code, because so much of it is really designed to ensure type safety and do compile-time metaprogramming magic, rather than to generate code.
Templates can be used to do a lot of different things. They can generate more code than you expect, but that's not a reason to ban their use. It wasn't so long ago that various authorities recommended avoiding exceptions, virtual functions, floating-point math, and even classes due to concerns about code size and performance, but people did those things, and somehow everything worked out fine.
Templates don't necessarily lead to code bloat. If you write a function or class template and instantiate it for a dozen different types then yes, you get a lot of duplicate code generated (probably, anyway. Some compilers can merge identical instantiations back together).
But if a template is instantiated for one type only, then there is zero cost in code size. If you instantiate it a couple of times, you pay a certain cost, but you'd also end up paying if you used any of the other ways to achieve the same thing. Dynamic polymorphism (virtual functions and inheritance) isn't free either. You pay for that in terms of vtables, code generated to facilitate all the type casts and conversions necessary, and simply because of code that can't be inlined or optimized away.
Taking std::vector as an example, then yes, if you use both vector<int> and vector<float>, you get two copies of some of the code. But with templates, only the code that is actually used gets compiled. The member functions that you never call won't generate any code, and even in the functions that are compiled, the compiler may be able to eliminate a lot of code. For example, for certain types, exception handling code may be unnecessary, so the compiler can eliminate it, yielding smaller code than if you'd used dynamic polymorphism, where the compiler would've been unable to make any assumptions about the type being stored. So in this made-up example, you'd get some code generated for both vector<int> and vector<float>, but each of them is going to be a lot smaller than a polymorphic vector as you might find in Java, for example.
The main problem with using templates is that it requires a compiler which supports it. On a PC, that's no problem. On any other platform which has a mature C++ compiler available, it's no problem.
But not all platforms have a modern heavy-duty C++ compiler available. Some don't support a number of advanced features, and some are just not good enough at the optimizations required to make template code work (templates tend to require a lot of inlining, for example). So on some platforms, it may be best to avoid templates. Not because of any concern for code size, but because the compiler may be unable to handle it.
In my personal experience using (and even abusing) templates very rarely result in large code bloat, and compiling with -Os will help a lot.
It's not that common to see huge template classes duplicated (instantiated) many times, both because rarely classes are huge, and because in most cases you only instantiate templates with a few different arguments, not hundreds. Besides it's easy to reuse some common code in your biggest template classes/functions, and compiler will help you in doing this.
Usually size of data (graphics, audio, ...) is orders of magnitude bigger than the code. So I wouldn't worry.
Of course there could be exceptions to what I said, but I guess they'll mostly be about advanced (special / weird / complicated) stuff, not with the most common everyday classes.
Summarizing my suggestion: use templates as much as you want, if something will go wrong you'll find that out by profiling, and you will easily be able to optimize the size.
Whatever you do, do NOT try writing some code, compile it, and compare executable size or code duplication.
I would say that generally (not just related to mobile development) this advice holds. Some of the techniques described in Modern C++ Design can lead to long build times and code bloat.
This is especially true when dealing with "obscure" devices, like cell phones. Many template techniques rely on that the compiler and linker do a perfect job in eliminating unused/duplicate code. If they don't, you risk having hundreds of duplicate std::vector instances scattered all over your code. And trust me, I have seen this happen.
This is not to say Modern C++ Design is a bad book, or that templates are bad. But especially on embedded projects it's best to watch out, because it can bite.

Programmer productivity with STL vs. custom utility classes

I work in an environment where, for historical reasons, we are using a hodgepodge of custom utility classes, most of which were written before STL arrived on the scene. There are many reasons why I think it is a good idea to at least write new code using STL, but the main one is that I believe it increases programmer productivity. Unfortunately, that is a point that I don't know how to prove.
Are there any studies out there that attempt to quantify, or even just hint at, a productivity gain from using STL?
Update: I guess I should have been more specific. I am not advocating rewriting existing code, and I am not worried about the new hires that will get a running start. The former would be foolish, and the latter by itself is not enough to convince people.
There are no studies that will show STL is more productive just because it is STL. Productivity gains from using it are due to it being a standard programmers are familiar with it, and because the code is already written and tested.
If your company already has utility classes that employees are familiar with, and this utility code is used throughout an existing codebase, then switching to STL could actually be detrimental to productivity.
That said for new code using STL would be a good move. I would not necessarily argue this from a productivity standpoint, but one of maintainability. If you have code that predates STL it sounds like code at your company has quite a long lifetime and is likely to be maintained by a number of new programmers over the years.
You may also want to broach the use of STL as a way for everyone to keep their C++ skillset sharp. While I wouldn't reject a C++ candidate who didn't know STL, I would definitely view it as a black mark.
The reason the STL is so "good" is simply because it's been around a long time now and the implementations have seen a lot of users and eyes. They're well debugged and the algorithms have been pretty well optimized by vendors.
STL will be more productive for new devs in your shop because it's likely they are already familiar with it. Your custom libs will be foreign and probably lacking in features that devs are accustomed to using. That's not a huge issue after the initial ramp-up period for new devs though.
There's no real pressing reason to shift to STL just because it is. If you have perfectly useful utility classes in your application I'd recommend sticking with them unless they're not workable for new code. Mixing STL with your custom libraries in new code is going to cause compatibility problems at some point and refactoring the code to use all STL is going to introduce bugs. Either way you'll be losing productivity.
Edit: By "new" code, I mean new code in existing applications using the older class libraries.
If you're developing new standalone apps that do not draw on any of the old applicaiton code I'd recommend STL because it's there, most every C++ dev knows how to use it and it's pretty stable (and you get support from your toolset vendor if it's not).
The only argument for increasing productivity with STL I can think of would be a possibility of integrating other libraries easily - Boost, Arabica, SOCI, etc. They are all designed to work with STL, not your in-house container classes.
I think the critical factor is the turnover rate of the development team.
If the team is stable, and they've been working on this code for ten years and probably will be ten years from now, they will be more productive using the utility classes they're familiar with, and nudging them to use the STL will result in reduced productivity and bugs.
If the team turns over a lot, then the new developers will likely be familiar with the STL, and obviously not this proprietary utility class library, and will do better with the STL.
I have been in the same situation. It depends on the utility classes in question. Many custom utility classes I have seen have been buggy, or poorly designed, and are causing bugs and inefficiencies throughout the source. In this case, a straight replacement with STL equivalents will improve the codebase, increase productivity, decrease bugs and reduce maintainance costs for the future.
You can sometimes help to bridge the gap between the two worlds by retrofitting STL-style iterators to your old classes, though be careful to get them right!
It may be that the reverse is true where the home-grown utilities are in any way domain-specific to the work you do.
One place where STL is useful is not in the actual libraries etc that are provide by STL but rather in the coding style that STL uses.
In the following there are 2 main tests required:
struct DoSomething {
bool operator ()(Container::value_type const & v) const
{
// ...
}
};
void bar (Container const & c)
{
std::for_each (c.begin (), c.end (), DoSomething ());
}
The first tests verify that 'DoSomething::operator()' does what it's supposed to do. The second test only needs to verify that 'DoSomething::operator()' is called.
This separation can help improve productivity when compared with a hand written for loop. For the above, the number of tests is the sum of the "thing to be done" and the tests that the call is made for a non empty container. In the case of the for loop the number of tests is the product of the tests.
The reasons I see are:
Quality of the code
The writers of the STL (either its interface, or the implementation for your compilers) are without doubts magnitudes better than the best developer in your company.
Their job is to make a usable STL, which means that every function/method/object is heavily tested anyway.
Maintainability of the code
With the turnover, some code can become slowly and stealthily unmaintained. Which means that if there is a bug in this code, or if its performance or interface are found lacking (see the "Quality" above), then you'll find no one to expertly improve it.
The code change will have a non-zero probability of a code regression elsewhere, and if your in-house library is not unit-tested, that this regression will go undetected for quite some time.
And I'm not even mentioning the "I WON'T ever touch that slimy code" syndrome when someone trying to correct the code just finds he doesn't understand why it was done this way (because of macros, strange pre-conditions, etc..
Conclusion
Combine the two, and you'll find that for generic code (i.e. arrays, strings, etc.), you'll go better by slowly migrating from in-house libraries to STL library, writting "converter functions" when needed.
I think this kind of migration is part of the maintenance of your code, and that you should slowly (i.e. with new code, or when refactoring), whenever possible, use STL instead of in-house generic libraries.
Since you already have the utility classes, there's no need for using the STL. It will quickly become a maintainability problem as you find the need to begin integrating the STL into your utility libraries. IMO, it will be a productivity loss.
That said, the STL may offer a lot of features and utilities that your utility libraries don't provide. (Particularly useful is the <algorithms> header, which you can probably begin using immediately without many problems with legacy code.) If you're writing a lot of new code, it's far better to use the STL (and Boost, if you can) than to write your own utility classes and algorithms. As a result, it will be a major productivity gain.
I don't know of any studies on the topic, though.
Consider the situation when you hire a new C++ programmer. Is s/he more likely to have experience with STL classes or your own ones? You could be looking at huge savings in time before they become productive if you start to switch to the STL.
Currently, any newly hired employee will have to learn how to use the old classes, and that costs time and money. Using STL like everyone else would save your company money and keep it attractive among the pool of candidates.
I don't think there is a way to justify replacing these custom classes wholesale, unfortunately. If possible, replace them with STL components a class at at time.
This is a maintenance & readability issue as much as anything. (1) Using STL helps maintainers understand the code at a glance, versus needeing to learn their way around custom implementations. (2) The STL is WELL documented and well understood - what about your custom classes? (3) The STL is well vetted. (4) The STL comes with asymptotic runtime upper & lower bounds.
Good luck.

What are the good and bad points of C++ templates? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I've been talking with friends and some completely agree that templates in C++ should be used, others disagree entirely.
Some of the good things are:
They are more safe to use (type safety).
They are a good way of doing generalizations for APIs.
What other good things can you tell me about C++ templates?
What bad things can you tell me about C++ templates?
Edit: One of the reasons I'm asking this is that I am studying for an exam and at the moment I am covering the topic of C++ templates. So I am trying to understand a bit more on them.
Templates are a very powerful mechanism which can simplify many things. However to use them properly requires much time and experience - in order to decide when their usage is appropriate.
For me the most important advantages are:
reducing the repetition of code (generic containers, algorithms)
reducing the repetition of code advanced (MPL and Fusion)
static polymorphism (=performance) and other compile time calculations
policy based design (flexibility, reusability, easier changes, etc)
increasing safety at no cost (i.e. dimension analysis via Boost Units, static assertions, concept checks)
functional programming (Phoenix), lazy evaluation, expression templates (we can create Domain-specific embedded languages in C++, we have great Proto library, we have Blitz++)
other less spectacular tools and tricks used in everyday life:
STL and the algorithms (what's the difference between for and for_each)
bind, lambda (or Phoenix) ( write clearer code, simplify things)
Boost Function (makes writing callbacks easier)
tuples (how to genericly hash a tuple? Use Fusion for example...)
TBB (parallel_for and other STL like algorithms and containers)
Can you imagine C++ without templates? Yes I can, in the early times you couldn't use them because of compiler limitations.
Would you write in C++ without templates? No, as I would lose many of the advantages mentioned above.
Downsides:
Compilation time (for example throw in Sprit, Phoenix, MPL and some Fusion and you can go for a coffee)
People who can use and understand templates are not that common (and these people are useful)
People who think that they can use and understand templates are quite common (and these people are dangerous, as they can make a hell out of your code. However most of them after some education/mentoring will join the group mentioned in the previous point)
template export support (lack of)
error messages could be less cryptic (after some learning you can find what you need, but still...)
I highly recommend the following books:
C++ Templates: The Complete Guide by David Vandevoorde and Nicolai Josuttis (thorough introduction to the subject of templates)
Modern C++ Design. Generic Programming and Design Patterns Applied by Andrei Alexandrescu (what is the less known way of using templates to simplify your code, make development easier and result in code robust to changes)
C++ Template Metaprogramming by David Abrahms and Aleksey Gutov (again - different way of using the templates)
More C++ Idioms from Wikibooks presents some nice ideas.
On the positive side, C++ templates:
Allow for generalization of type
Decrease the amount of redundant code you need to type
Help to build type-safe code
Are evaluated at compile-time
Can increase performance (as an alternative to polymorphism)
Help to build very powerful libraries
On the negative side:
Can get complicated quickly if one isn't careful
Most compilers give cryptic error messages
It can be difficult to use/debug highly templated code
Have at least one syntactic quirk ( the >> operator can interfere with templates)
Help make C++ very difficult to parse
All in all, careful consideration should be used as to when to use templates.
My 2c are rather negative.
C++ types were never designed to perform compile time calculations.
The notion of using types to achieve computational goals is very
clearly a hack – and moreover, one that was never sought but rather
stumbled upon
..
The reward for using MP in your code is the moment of satisfaction of
having solved a hard riddle. You did stuff in 100 lines that would
have otherwise taken 200. You grinded your way through
incomprehensible error messages to get to a point where if you needed
to extend the code to a new case, you would know the exact 3-line
template function to overload. Your maintainers, of course, would have
to invest infinitely more to achieve the same.
Good points: powerful; allows you to:
prescribe compile-time attributes and computation
describe generic algorithms and datastructures
do many other things that would otherwise be repetitive, boring, and mistake-prone
does them in-language, without macros (which can be far more hazardous and obscure!)
Bad points: powerful; allows you to:
provoke compile-time errors that are verbose, misleading, and obscure (though not as obscure and misleading as macros...)
create obscure and hazardous misdesigns (though not as readily as macros...)
cause code bloat if you're not careful (just like macros!)
Templates vastly increase the viable design space, which is not necessarily a bad thing, but it does make them that much harder to use well. Template code needs maintainters who understand not just the language features, but the design consequences of the language features; practically speaking, this means many developer groups avoid all but the simplest and most institutionalized applications of C++ templates.
In general, templates make the language much more complicated (and difficult to implement correctly!). Templates were not intentionally designed to be Turing-complete, but they are anyway -- thus, even though they can do just about anything, using them may turn out to be more trouble than it's worth.
Templates should be used sparingly.
"Awful to debug" and "hard to read" aren't great arguments against good template uses with good abstractions.
Better negative arguments would go towards the fact that the STL has a lot of "gotchas", and using templates for purposes the STL already covers is reinventing the wheel. Templates also increase link time, which can be a concern for some projects, and have a lot of idiosyncrasies in their syntax that can be arcane to people.
But the positives with generic code reuse, type traits, reflection, smart pointers, and even metaprograms often outweigh the negatives. The thing you have to be sure of is that templates are always used carefully and sparingly. They're not the best solution in every case, and often not even the second or third best solution.
You need people with enough experience writing them that they can avoid all the pitfalls and have a good radar for when the templates will complicate things more than helping.
One of the disadvantages I haven't seen mentioned yet is the subtle semantic differences between regular classes and instantiations of class templates. I can think of:
typedefed typenames in ancestor types aren't inherited by template classes.
The need to sprinkle typename and template keywords in appropriate places.
Member function templates cannot be virtual.
These things can usually be overcome, but they're a pain.
Some people hate templates (I do) because:
On maintainability pov, the wrong use of templates can have a negative effect ten times stronger than the initial advantage of time they were supposed to bring.
On optimization pov, compiler optimizations they allow are nothing compared to an optimal algorithm and the use of multi threading.
On compiling time pov, wrong use of templates can a very negative effect on parsing, compilation and linking phases, when poorly written templated declaration brings tons of useless parasite declarations in each compilation units (here is how 200 lines of code can produce an .obj of 1Mb).
To me templates are like a chainsaw with an integrated flame thrower that can also launch grenades. One time in my life I may have a specific need of that. But most of the time, I'm using a regular hammer and a simple saw to build things and I'm doing a pretty good job that way.
Advantage: Generic Datatypes can be created.
Disadvantage: Code Bloating
I don't see how they are hard to read. What is unreadable about
vector <string> names;
for example? What would you replace it with?
Reusable code is made with template. Its application is in accordance with the profile of each.

Drawbacks to templates and the STL in C++ [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Are there any drawbacks to using the STL or templates. Are there any situations for which they are inappropriate.
First, you should use probably use them if they help you solve your problem. Templates are a very important part of C++ and have been part of the standard for years. STL is very powerful and fast at run time and should be supported on all decent compilers, but of course there are issues.
If you have a really old compiler, STL might not be completely supported.
The thread-safety of the STL implementation might be work for your application
Templates can lead to slower compile-times and possibly larger executable, especially with older compilers.
Compilers often produce incomprehensible error messages on code using templates.
just to name a few, but the drawbacks of not using them are likely to be much greater.
Obvious disadvantages:
The syntax can be horrible - some bits of template syntax in C++ are really pushing the limits of sanity, and overlap with other parts of the language (e.g. >>)
Lots of people don't understand the STL very well, so you might restrict your audience.
Error messages tend to be hideously complicated.
The design of the STL collections tends to lead to a lot of copying of objects. The original 'smart pointer' (std::auto_ptr) wasn't suitable for use in most collections. Things have improved in this regard recently (TR1)
There are several potential benefits and drawbacks
Templates expand the size of the resulting code.
Templated code is expanded and processed at compile time which may make compile times longer. (On the other hand, executable code may be more efficient).
Mis-used STL elements can result in slower code
The STL actually makes code more readable (my opinion differs from Will's). Like any language or library, you have to understand it to use it appropriately... which is a drawback for people who don't know it.
If you are using templates in a meta-programming sense (don't confuse w/ using the STL), the code looks like a language completely different from C++. It can be harder to parse through what the code is actually doing. (OTOH, done right - meta-programming makes you focus on architecture and design; it also brings more of the errors to compile time vs. runtime. This is a big win when you have a critical feature and you can catch an incorrectly coded piece at compile time rather than having a customer catch it during operation!)
Having said that, we use C++ and templates (and in some areas, meta-programming techniques) to the benefit of our overall code base. The code is slightly larger than it might be without templates, but the trade-offs in performance and maintainability outweigh the size. We do have skilled/experienced C++ programmers working on developing and maintaining the code.
If you're using drawbacks to decide whether to use C++ features/libraries or not - make sure you equally weigh the benefits both for the language and what your project/product/company is willing to trade off. Hope this helps.
Edit: One other major drawback I forgot to mention - portability. If you need to write portable code, templates may not be the right way to go. Most popular compilers today support the STL, however most is not all. The meta-programming techniques can be real killers to portability, so that is a definite consideration for deciding appropriateness of its use.
For embedded device programming (in my case -- smartphones). Templates are discouraged because of the concern for generated code size (small amount of RAM and disk space). Also the compilers are pretty ancient and probably can't handle some template related constructs.
Heavy template abuse (in particular
template meta-programming and Boost
addiction) can lead to excessively
long compile and link times.
You also wind up with executables
that have considerably larger
(unstripped) binaries, but generally
that isn't a terrible issue.
Poorly designed templates can also
increase code duplication further
exacerbating the executable size
issue.
For class templates with large
implementations also need to
consider the fact that using a
template for them means moving the
entire class body into a header
somewhere. This places a lot more
load on the linker if the template
is used in multiple places.
Error messages from heavily templated code can be daunting to the uninitiated and are rarely if ever as clear as the error messages you get from untemplated code.
That said, for most applications templates are a wonderful tool for code reuse and help lift the level of discourse from reimplementing to reusing code; rarely do these issues trump the benefits.
To paraphrase Andrei Alexandrescu of Modern C++ Design fame. Template are an orthogonal structure to multiple inheritance. They both have complementary trade-offs and benefits. Templates have rich mechanics but specialization of templates does not scale.
The goal of template is to provide abstraction with minimal performance penalty. In most cases, benefits outweigh drawbacks. Most of the issues with templates are from compiler and debugger support.
My pet peeve about template: it defeats smart build system due to header dependencies. Developing template code tends to cause a lot more recompilation of untouched code than developing a pure OO based system, especially if the latter use the DIP (dependency inversion principle) well. This exacerbates the slow compilation problem. OTOH, faster dev hardware these days make things much more tolerable than before.
As for STL (as well as Boost), their goal is to provide portable and reasonably efficient data structure and algorithms. They're not necessary the best choice for certain performance critical applications. For example: although hash_map (tr1/unordered_map) performs reasonably well for average cases, special purpose hash tables (e.g., the google sparse/dense hash table library) can greatly outperform generic STL implementations in terms of memory usage or speed.
There are a lot of philosophical (at best) arguments for and against C++ templates, but the one that I tend to accept the most is that the mechanism by which they are instantiated at compile time generates a considerable amount of code bloat.
While this isn't typically much of a concern, when you're writing code for an embedded system with very limiting restrictions on binary size it makes a significant impact.
In the MSVC implementation, std::string has an overhead of 26 bytes PER STRING, even if the string is empty. If you were doing just char*, it would be 4 bytes per string.
Complex STL containers (and for that matter any complex C++ class) make debugging much more difficult.
Besides the unreadable error messages mentioned before, there is usually very little support in current debuggers for handling STL constructs. For example, it is much easier to examine a native C array at runtime, than a vector<> container.
Hopefully the situation will change with time.
Other than that, templates are wonderful.
One might be that they translate poorly to other object-oriented languages that don't support templates such as C# and Java, so if you have a developer group coming from those languages, they will face a steeper learning curve.
The way templates get instantiated requires you to be careful about how to declare and define your templates when you share them across translation units. The book "C++ templates: The complete guide" is a good source of information about how to handle this.
Compiler and linker error messages for templates tend to be very, very verbose. You'll have to get used to that, and I think there are some scripts/tools that make them more readable, but I don't have any experience with them.
But apart from that templates are great!
See the templates section of the C++ FQA [sic] for lots of good reasons to not use templates.

Are C++ meta-templates required knowledge for programmers?

In my experience Meta-templates are really fun (when your compilers are compliant), and can give good performance boosts, and luckily I'm surrounded by seasoned C++ programmers that also grok meta-templates, however occasionally a new developer arrives and can't make heads or tails of some of the meta-template tricks we use (mostly Andrei Alenxandrescu stuff), for a few weeks until he gets initiated appropriately.
So I was wondering what's the situation for other C++ programmers out there?
Should meta-template programming be something C++ programmers should be "required" to know (excluding entry level students of course), or not?
Edit: Note my question is related to production code and not little samples or prototypes
If you can you find enough candidates who really know template meta-programing then by all means, require it. You will be showing a lot of qualified and potentially productive people the door (there are plenty of legitimate reasons not to know how to do this, namely that if you do it on a lot of platforms, you will create code that can't compile, or that average developers will have trouble understanding). Template meta-programming is great, but let's face it, it's pushing C++ to the limit.
Now, a candidate should probably understand basics (compute n! at compile time, or at least explain how it works if they are shown the code). If your new developers are reliably becoming productive within a few weeks, then your current recruiting is probably pretty good.
Yes, but I would not personally place a high priority on it. It's a nifty feature, but it's a bit situational, and good C++ code can be developed without it. I've personally used it once or twice, but haven't really found it to be valuable enough in my work to regularly use it. (Maybe that's a function of my lack of C++ production experience, though)
The only use I've ever made of template metaprogramming in production code is to unroll a critical loop which read a hardware register N times, followed by another M times, N, M different for different hardware and known at compile time. In general, the techniques don't seem a natural fit for our codebase, and I'd never get them through a code review.
Required? As always, it depends. For those of us in embedded land who are just now getting semi-decent C++ compilers for our tiny little DSPs and what not, we're just happy to be able to use classes.
However, if you've got a halfway decent C++ compiler, say gcc 3.3ish+, then yes, you should look at template metaprogramming. A good start is the boost library, of course, because it covers most of the templates you seem to look around for when the STL runs out of gas. It also serves as a great jumping off point.
However, sometimes I find that the advantages of template metaprogramming (lots of nice type safe code with a few lines of < and >) aren't worth the cost that it's going to take. Sometimes, a good old for( container::const_iterator iter = ... ) does what you need just fine.
18 months later and this topic is still very relevent. I would still say that template meta programming is not required knowledge, but you need to be able to at least read and explain the basics such as conditionals and the curiously repeating template pattern (looping). Beyond that, as long as you have a few people who can write a good interface to it, then just basic to intermediate template knowledge is all that is really required, though YMMV.
As someone who makes reasonable (although not extensive) use of templates and meta-programming, I go out of my way to try to make the interfaces (and by that I mean the internal usage interfaces) as normal as possible. Not everyone can understand templates, and even those that can sometimes cannot understand complex or obtuse meta programming paradigms.
With that said, if you want to dig in a modify my low-level libraries, you're going to have to know quite a bit. However, you should not even have to know templates (aside from baseline knowledge) to use them. That's how I draw the line at least, and the knowledge level I would expect in other developers (depending on how they are using the code).
I wouldn't consider template programming required, but it's definitely good to know. You should know enough about the subject to be able to effectively use template libraries such as the STL or Boost.
When I interview someone, I will always ask some questions about template meta-programming. If the candidate doesn't know about the subject, I would never hold that against them. But if they do, then it's a big plus in their favor.
It's not absolutely necessary to know how to use C++ templates. You can do most things without them. They are however a fantastic feature.
Since you roll your own templates, anyone new is going to have to come up to speed with them just like the rest of your code which is going to be the bigger chunk of the learning.
I encourage people to learn to use some of the features of the STL. I have used this library in production code and it does save time and simplify things quite a bit. I also roll my own when the need arises.
I've also heard good things about the boost library.
If I need to write portable code then I'll generally stick away from templates because many compilers still don't support them properly. If you need a portable STL then STLPort is the most portable.