35

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.

fmsf
  • 36,317
  • 49
  • 147
  • 195

10 Answers10

59

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:

Anonymous
  • 18,162
  • 2
  • 41
  • 64
  • 2
    You forgto to mention that size of the produced code also increases. That is why templates are rarely used in embedded devices with very low storage capacity (unless you define the template inside the source file (that is make it accessable ONLY inside that source file and not to any other that imports the source file's header). – rbaleksandar Apr 19 '17 at 07:24
  • @rbaleksandar That's not necessarily true. People who say templates increase code often aren't comparing like for like - they're comparing template code to an alternate solution to the problem, not comparing template code to the equivalent non-template code. – Pharap Jul 21 '18 at 21:20
  • @Pharap Java uses type erasure to reduce the generated code.. Why C++ doesn't have that feature? – Sourav Kannantha B Feb 10 '21 at 13:55
  • @SouravKannanthaB Three reasons: 1) Because [Type Erasure has its own set of flaws](https://en.wikipedia.org/wiki/Generics_in_Java#Problems_with_type_erasure). 2) Because C++ and Java function very differently 'under the hood'. C++ compiles to machine code and deals with objects directly, Java uses bytecode and every field and variable is an opaque reference to the actual object. 3) Because large executables aren't a big problem. Storage space gets cheaper as time goes by, and even large programs tend to be smaller than high-quality images and video. – Pharap Mar 19 '21 at 08:52
  • 1
    @SouravKannanthaB That said, [it is actually possible to do type erasure in C++](https://devtut.github.io/cpp/type-erasure.html). For example, the `std::function` type uses type erasure to allow it to refer to both function pointers and lambda functions. This is an example of where type erasure can be useful, but in general type erasure has a lot of flaws compared to reified generics or templates, which is why most languages opt for a better approach in general. – Pharap Mar 19 '21 at 08:56
  • @Pharap yeah.. I got it late. Type erasures only work in single rooted inheritance. Still.. I don't know any language apart from C++ which uses refied types. – Sourav Kannantha B Mar 19 '21 at 12:37
  • @SouravKannanthaB I'm fairly sure C++'s templates don't actually count as reified generics because the type information isn't available at runtime. C# is an example of a language that uses reified generics - where the type of the generic parameter is available at runtime. There's a good SO answer about the three different approaches [here](https://stackoverflow.com/a/31876747). Kotlin is an example of a language targetting the JVM that uses reified generics, but its approach is more costly compared to C#'s generics because the CLR has proper support for reification and the JVM doesn't. – Pharap Mar 20 '21 at 07:35
19

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.

Paul
  • 6,435
  • 4
  • 34
  • 45
9

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.

Ofek Shilon
  • 14,734
  • 5
  • 67
  • 101
  • 2
    I do agree, I see myself in every day coding more disadvantage using templates than advantage, specially with your second point. – Alexis Pautrot Feb 04 '16 at 16:46
4

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.

3

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.

Dan Olson
  • 22,849
  • 4
  • 42
  • 56
2

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.

Alexis Pautrot
  • 1,128
  • 1
  • 14
  • 18
2

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:

  1. typedefed typenames in ancestor types aren't inherited by template classes.
  2. The need to sprinkle typename and template keywords in appropriate places.
  3. Member function templates cannot be virtual.

These things can usually be overcome, but they're a pain.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
1

Advantage: Generic Datatypes can be created.

Disadvantage: Code Bloating

Vinay
  • 4,743
  • 7
  • 33
  • 43
0

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?

  • I mean the template source code, I'll correct it on the question – fmsf Mar 07 '09 at 22:53
  • 31
    vector? Did you mean vector, allocator >, allocator, allocator > > >? – Thomas Mar 07 '09 at 23:55
  • @Thomas, what's wrong with that? – greyfade Mar 08 '09 at 02:09
  • 7
    @greyfade: If you enjoy working with types like that, I've got a few pages of template compiler error messages here that you'd just *love*. – j_random_hacker Mar 08 '09 at 07:17
  • @Thomas, @j_random_hacker Give us the alternative (generic, versatile, robust) then. As for reading the errors, after some time you can get quite skilled with it and filter crap instantaneously. One day of Spirit or Phoenix and +10 in error reading skill ;) – Anonymous Mar 08 '09 at 09:30
  • STLfilt is our friend: it simplifies the error messages to keep only what is relevant. – Luc Hermitte Mar 09 '09 at 19:18
  • 2
    @Thomas. typedef basic_string, allocator >, allocator, allocator > > string; 'nuff said. – Ed James Mar 11 '09 at 17:23
  • @Ed: And yet,it's no different in terms of structure than a simple function call. You have the class template, followed by the template arguments. Replace angle brackets with parens, and it should look very familiar. It's verbose, yes, but that's because it's customizable, not because of templates. – jalf Mar 16 '09 at 20:27
-2

Reusable code is made with template. Its application is in accordance with the profile of each.

lsalamon
  • 7,998
  • 6
  • 50
  • 63