12

Some of the disadvantages would be

  1. its syntax is complex
  2. compiler generates extra code
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
anish
  • 1,035
  • 4
  • 13
  • 27
  • 7
    **compiler generates extra code**, I've read somewhere (mr. Stroustrup, I think) that on modern compilers actually not - no single instruction overhead – Alexander Malakhov Apr 29 '10 at 05:48
  • 6
    I don't by the "complex syntax" argument. If you find template syntax confusing, one should be focusing on continuing to learn the language, not pick at it. And 2 should be largely irrelevant, IIRC. – GManNickG Apr 29 '10 at 05:51
  • @GMan - Save the Unicorns totally agree – anish Apr 29 '10 at 05:53
  • 3
    I think the extra code happens e.g. when you instantiate your templated container against N different types, and the compiler generates N slightly-different versions of the container code. (Compare that to the classic method where you hand-code a single container class that can hold any type of object... unsafe at runtime, but only one copy of the container code is generated) – Jeremy Friesner Apr 29 '10 at 05:58
  • @GMan - Save the Unicorns, (2) should be largely irrelevant unless you happen to write code for an embedded system where flash space and memory are scarce. – Alex B Apr 29 '10 at 06:03
  • @Checkers: I mean irrelevant as in the compiler will combine all the same functions, and you're left with minimal code. The only way to go "more minimal" is to make one container that just points to arbitrary data, which is less safe, probably slower, but takes up less space. – GManNickG Apr 29 '10 at 06:11
  • 3
    @Checkers: If your compiler cannot fold duplicate identical code generated from templates, there's techniques to - safely! - do this in code (like basing all `T*` instances on a `void*` with a thin compile-time wrapper around it for type-safety). – sbi Apr 29 '10 at 06:14
  • 1
    @anish and Checkers: You don't need to include the full alias for notifications *(and you can't notify me ;)*, see http://blog.stackoverflow.com/2010/01/new-improved-comments-with-reply/ – Georg Fritzsche Apr 29 '10 at 06:18
  • @Alexander: That's not the case, I've seen extra code being generated for special cases. For example, I created a FFT implementation that relied on template arguments to do it's recursion. However in specific cases where some template argument was 2 or less the compiler generated more optimal code because it could remove some calculations. Thus, the compiler generated more better code. – Jasper Bekkers Apr 29 '10 at 17:27
  • templates don't generate extra code, templates generate _less_ code. However, the downside is that templates make it extremely easy for _you_ to generate extra code. – Mooing Duck Jul 12 '14 at 19:54

11 Answers11

27

They are hard to validate. Template code which doesn't get used tends to be seldom compiled at all. Therefore good coverage of test cases is a must. But testing is time-consuming, and then it may turn out the code never needed to be robust in the first place.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • That's an interesting one I hadn't considered before. – j_random_hacker Apr 29 '10 at 06:43
  • 4
    Another problem may be that templates can be used to *prevent* code from compiling: for example, ensuring that a class template is never instantiated with certain template parameters. It's generally hard to write tests verifying that code does not compile. :) – jalf Apr 29 '10 at 17:56
  • This is a good one, it's hard to make sure that all template methods work properly with a variety of data types when you may not need the full interface initially. – Mark B Apr 29 '10 at 19:35
25

Hmm, how about...

3: They can be slow to compile

4: They force things to be calculated at compile time rather than run time (this can also be an advantage, if you prefer fast execution speed over runtime flexibility)

5: Older C++ compilers don't handle them, or don't handle them correctly

6: The error messages that they generate when you don't get the code right can be nearly incomprehensible

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • 9
    I disagree with 4. Use templates when appropriate, if you need run-time flexibility, don't use a template. 5 shouldn't matter except in old code bases where complaining about a language doesn't make sense. Modern compilers are either free or cheap. 6 is iffy. :P Understand templates and the errors are understandable. – GManNickG Apr 29 '10 at 05:52
  • 8
    Well, he asked for any disadvantages, not only insurmountable disadvantages :) – Jeremy Friesner Apr 29 '10 at 05:59
  • 12
    @GMan: I disagree with your POV re #6. For the innocent looking `std::list l; std::sort(l.begin(),l.end());` VC9 spits a 7.5kB error message at you, all of which point into std lib headers. Even if I fully understand why sorting a list that way doesn't work, 7.5kB of error messages are far too much to understand. – sbi Apr 29 '10 at 06:11
  • Anyway, +1 from me, even though I would start this list with #2, since anish's #2 is bogus. – sbi Apr 29 '10 at 06:13
  • @sbi: Eh, tested it and the errors are still completely understandable. I guess for me understandable means you can understand what caused the errors, and for you it means the same thing but in a concise manner. :) But a +1 from me too, probably the best list. – GManNickG Apr 29 '10 at 06:19
  • 1
    @GMan: It's 28 error messages here, _one_ of which points to my code, and that says `see reference to function template instantiation 'void std::sort::_Iterator<_Secure_validation>>(_RanIt,_RanIt)' being compiled` - which is a _very_ warped version of what I invoked. You should see how humble fellow-workers approach my desk when they run into one of these. And the first view is always at the code they wrote, because understanding what went wrong from looking at your own code (_not_ the error messages it causes) usually is your best bet. __And that's just plain wrong__. – sbi Apr 29 '10 at 06:26
  • @sbi: Still understandable. :/ – GManNickG Apr 29 '10 at 06:43
  • 1
    @GMan: Try a `boost::bind()` expression then where you are just missing one placeholder - still understandable? – Georg Fritzsche Apr 29 '10 at 06:54
  • 1
    @gf: Yes, but now you're cheating. :P – GManNickG Apr 29 '10 at 07:22
  • 4
    I'd say the *main* disadvantage with templates is poor error messages. They're not *easily* understandable, which is part of the reason concepts were going to be added to C++0x: to improve diagnostics. I'd say I understand templates very well, but even a mistake as simple as having a protected destructor on a class stored in a `unique_ptr` left me pondering a page-long error message for some time. Not helpful. (Yes, I'm stupid for doing that :P but people fat-finger things all the time, which is why good diagnostics are important) – AshleysBrain Apr 29 '10 at 09:30
12

Templates expose your implementation to the clients of your code, which makes maintaining your ABI harder if you pass templated objects at library boundaries.

Alex B
  • 82,554
  • 44
  • 203
  • 280
11

So far no-one seems to have mentioned the main disadvantage I find with templates: code readability plummets!

I'm not referring to syntax issues -- yes the syntax is ugly, but I can forgive that. What I mean is this: I find that with never-seen-before non-templated code, however large the application is, if I start at main() I can usually decode the broad strokes of what a program is doing without problems. And code that merely uses vector<int> or similar doesn't bother me in the slightest. But once code starts to define and use its own templates for purposes beyond simple container types, understandability rapidly goes out the window. And that has very negative implications for code maintenance.

Part of that is unavoidable: templates afford greater expressiveness via the complicated partial-order overload resolution rules (for function templates) and, to a lesser degree, partial specialisation (for class templates). But the rules are so damn complicated that even compiler writers (who I'm happy to acknowledge as being an order of magnitude smarter than I am) are still getting them wrong in corner cases.

The interaction of namespaces, friends, inheritance, overloading, automatic conversions and argument-dependent lookup in C++ is already complicated enough. But when you add templates into the mix, as well as the slight changes to rules for name lookup and automatic conversions that they come with, the complexity can reach proportions that, I would argue, no human can deal with. I just don't trust myself to read and understand code that makes use of all these constructs.


An unrelated difficulty with templates is that debuggers still have difficulty showing the contents of STL containers naturally (as compared to, say, C-style arrays).

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
  • 1
    Template meta-programming can be a maintenance problem, sure. But more standard usage of templates is something all frequent C++ coders need to be able to grasp. I've had the opposite experience with debugging STL containers, at least with Visual Studio. std::vector, for example, is shown in the watch window as a collapsible entry that expands to the correct size of the container. With C-style arrays, you have to use the uglier "myArray,n" syntax, manually specifying the size of the array. The difference is even more dramatic with std::list or std::map vs. hand-written counterparts. – Ben May 05 '10 at 01:17
  • Thanks Ben, yes it's TMP that causes the most headaches. And that's good news about Visual Studio, I must have been summoning frustration caused by an earlier version. Or is that a feature of non-Express editions only? – j_random_hacker May 05 '10 at 05:38
10

The only real disadvantage is that if you make any tiny syntax error in a template (especially one used by other templates) the error messages are not gonna be helpful... expect a couple pages of almost-unusable error msgs;-). Compilers' defect are very compiler-specific, and the syntax, while ugly, is not really "complex". All in all, though -- despite the huge issue with proper error diagnostics -- templates are still the single best thing about C++, the one thing that might well tempt you to use C++ over other languages with inferior implementations of generics, such as Java...

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
4

They're complicated for the compiler to parse which means your compilation time will increase. Also it can be hard to parse compiler error messages if you have advanced template constructions.

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
3

Less people understand them, epsecially at the level of meta programming, therefore less people can maintain them.

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
2

When you use templates, your compiler only generates what you actually use. I don't think there is any disadvantages in using C++ template meta-programming except the compiling time which can be quite long if you used very complex structures as boost or loki libraries do.

Opera
  • 983
  • 1
  • 6
  • 17
1

A disadvantage: template errors are only detected by the compiler when the template is instantiated. Sometimes, errors in the methods of templates are only detected when the member method is instantiated, regardless if the rest of the template is instantiated.

If I have an error in a method, of a template class, that only one function references, but other code uses the template without that method, the compiler will not generate an error until the erroneous method is instantiated.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • +1, but it would be more accurate to say that there are *some* errors that are not detected until the template is instantiated. Syntax errors, and type errors involving only non-dependent types, will be found at definition time. – j_random_hacker Apr 30 '10 at 05:08
1

The absolute worst: The compiler error messages you get from bad template code.

Earlz
  • 62,085
  • 98
  • 303
  • 499
0

I have used templates sometimes over the years. They can be handy but from a professional perspective, I am leaning away from them. Two of the reasons are:

1.

The need to either a.) expose the function definitions (not only declarations) "source" code to the "where used" code or b.) create a dummy instantiation in the source file. This is needed for compilation. Option a.) can be done by defining functions in the header or actually including the cpp.

One of the reasons that we tolerate headers in C++ (compared to C# for example) is because of the separation of "interface" from "implementation". Well, templates seem to be inconsistent with this philosophy.

2.

Functions called by a template type parameter instantiation may not be enforced at compile time resulting in link errors. E.g. T example; example.CompilerDoesntKnowIfThisFunctionExistsOnT(); This is "loose" IMHO.

Solutions:

Rather then templates, I lean towards using a base class whereby the derived/container classes know what is available at compile time. The base classes can provide the generic methods and "types" that templates are often used for. This is why source code availability can be helpful if existing code needs to be modified to insert a generic base class in the inheritance hierarchy where needed. Otherwise if, code is closed source, rewrite it better using generic base classes instead of using a template as a work around.

If type is unimportant e.g. vector< T > then how about just using"object". C++ has not provided an "object" keyword and I have proposed to Dr. Bjarne Stroustrup that this would be helpful especially to tell compiler and people reading code that type is not important (for cases when it isn't). I don't that think C++11 has this, perhaps C++14 will?

Community
  • 1
  • 1