Slashdot Mirror


C++ Templates: The Complete Guide

nellardo writes "The book C++ Templates: The Complete Guide, by Vandevoorde and Josuttis, Addison-Wesley 2003, is an authoritative treatment of exactly what it claims: the template mechanism of C++. If you are a C++ programmer, you should have this book on your shelf. If you aren't a C++ programmer, move along -- this book is highly specific to C++, and won't be much help in understanding the template mechanisms of other languages. Of course, if you aren't a C++ programmer, you probably wouldn't even give this book a second glance in the first place." Read on for the rest of Brook's review. C++ Templates: The Complete Guide author David Vandevoorde & Nicolai M. Josuttis pages 528 publisher Addison Wesley rating 10 for C++ programmers, 0 for anyone else. reviewer Brook Conner ISBN 0201734842 summary A thorough, exhaustively complete treatment of a complex subject. An essential reference for C++ programmers and a lengthy and boring book for anyone else.

The C++ programming language is widely regarded as a good systems programming language, albeit a complex one fraught with low-level details and issues (though arguably this is what makes it good for certain kinds of systems programming). For perhaps a decade now, C++ has had a template mechanism - in programming language circles, it might more properly be called a form of parametric polymorphism. The template mechanism, like many other forms of parametric polymorphism, is potentially extremely powerful, but the complexity of C++ makes it tough to thoroughly master. That's where this book comes in.

Most likely, an experienced C++ programmer has at least used templates. If nothing else, use of the Standard Template Library (or STL) requires at least knowledge of how to use templates. If you use C++ enough to care about templates, you probably know what they are, at least roughly, and if you don't, this isn't the book from which to learn about them. It very clearly requires (and explicitly states in the introduction) that you need to know C++ before making effective use of the book.

Designing template classes, however, is another kettle of fish, and if you're in a position where you're building template classes for someone else to use, you probably need this book. Unless, like the book's authors, you moderate comp.lang.c++.moderated. If you are such a super C++ guru, you may still find this book useful - it is a truly stupendous catalog of the capabilities and subtleties of C++ templates. If nothing else, you'll find examples for well nigh every use to which you are likely to put C++ templates.

The book's strengths, then, are its authoritative and exhaustive detail. On the downside, its examples are dry and flavorless. Perhaps this is intentional, as a way to suggest how some feature can be used in a variety of situations. I prefer a combination of specific, concrete examples, followed by a generic example. The specifics motivate the need for a capability, while the generic showcases the broad, interrelated aspects of the capability. The authors didn't follow that approach. I would suspect this comes in part from their mutual roles in C++ standards bodies - a specific example could be seen as too limiting, and so were left out.

Another drawback, to my thinking, is its resolute focus on C++ to the exclusion of all other languages. Don't get me wrong - I read the title, and it's a C++ book, so I don't expect it to teach me Scheme, much less Haskell. However, I think the complexities of C++ templates might have been easier to tackle and understand with at least pointers to other ways it could have been (and has been) done. If nothing else, citations of alternative approaches would be a useful source for the motivated reader. As it is, it doesn't even deal with differences between C++ implementations - it doesn't even list GCC in the index.

All in all, though, C++ Templates: The Complete Guide is exactly what it claims to be. It's an in-depth treatment of C++ templates and how they work. It isn't a cookbook for practical applications, nor is it a guide to further in-depth exploration of parametric polymorphism. But it is definitely a handy reference for the working C++ programmer to have on her shelf. If you're a working C++ programmer, I'd recommend it. If you aren't, you might want to pass on this one.

You can purchase C++ Templates: The Complete Guide from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

70 of 371 comments (clear)

  1. Re:Are templates always necessary? by tomhudson · · Score: 4, Insightful

    But then you loose the flexibility of multiple inheritance if everything ultimately has a single parent. It's always going to be a trade-off. If there was "one right way" to do everything, we'd all be out of jobs within the next decade :-)

  2. Re:Are templates always necessary? by syle · · Score: 2, Informative

    Hi, have you ever heard of the STL?

    --

    /syle

  3. Bloat by warmcat · · Score: 2, Insightful

    I have used C+ for several years, and love its abilities to model layers of belongingness with its OO principles: but I assessed templates as evil and have never used them. My understanding is that the template mechanism is like a super #define, that is, the compiler spawns multiple implementations of templated classes.

    The seemed to me a recipe for bloat/cache thrashing/ugliness. I did not see bloat addressed in the review. In my reactionary way I continue to believe my prejudices.

    Does anyone who has used templates have anything to say about templates and bloat?

    1. Re:Bloat by Buck2 · · Score: 5, Insightful

      I'm just throwing this out there but anyone that knows any better please feel free to present an argument:

      We use the blitz++ library in our laboratory due to benchmark findings that it is an extraordinarily fast package of matrix-type operations. It has been repeatedly argued that the speed of the library is due to the fact that it is entirely (I believe) implemented with templates.

      If you'd like to read some hairy code ... check out blitz++. :) And the errors you can get when compiling are simply astounding. AFAICT, though, it's damn fast.

      So, no, templates don't necessarily lead to bloating/ugliness/slowdowns/whatever if done properly.

      --

      As my father lik@(munch munch)... ....
    2. Re:Bloat by Malc · · Score: 4, Insightful

      I use templates with virtually every class and method I write: the STL. I couldn't live without it. It simplifies my development efforts, and helps me produce C++ solutions faster and with greater reliability. So far none of the applications have needed performance tuning. I'm sure there are situations where it is in appropriate, just not in my circles. I shudder when I think back to my C++ days prior to using the STL. So, I'm all for it and the ditching of the pre-processor and basing things on void*.

    3. Re:Bloat by Malc · · Score: 4, Interesting

      "If you'd like to read some hairy code ... check out blitz++. :) And the errors you can get when compiling are simply astounding."

      That is my biggest complaint with templates. Compilation errors can be horrendous, especially as they often appear far from point where you've made the error. My second biggest complaint are the debugger symbols that get produced for templates.

    4. Re:Bloat by Henry+V+.009 · · Score: 2, Interesting

      They give the developer parametric polymorphism at design time, so she can deal with one "customizable" class instead of 20 slight modifications.

      I gotta ask, when you think of a programmer, do you actually think of a girl programming? I mean good god, that 'she' thing as the neutral pronoun is more than a little phony isn't it? More women are graduating from colleges than men. They simply aren't choosing programming as a career in large numbers. Sorry, but it's a male-orientated profession. And I happen to know that you, as a human being, when you think of some generic programmer, think of a male. Probably a fat, coca-cola guzzling male.

      Despite that mental image, your instinct for double-think kicks in. You choose the female pronoun for a host of social reasons.

      And sorry, I don't like double-think, so I'm attacking you for it. Nobody talks like that in normal conversation. It's a middle-school English teacher grammar meme. A virus.

    5. Re:Bloat by jkujawa · · Score: 2, Interesting

      You cannot use C++ effectively and safely without templates.

      The STL, especially, makes C++ an order of magnitude more usable and powerful.

    6. Re:Bloat by Gortbusters.org · · Score: 3, Insightful

      True that. Not using the STL is like saying you will rewrite the entire Java API for your application, save the base Object.

      Some people say they use the good ole void* instead of a template. Those people sometimes do memory debugging for months.

      --
      --------
      Free your mind.
    7. Re:Bloat by Waffle+Iron · · Score: 3, Redundant
      The seemed to me a recipe for bloat/cache thrashing/ugliness.

      No, templates are often anti-bloat. With a good optimizing compiler, a dizzying heirarchy of layers of abstraction can often compile down to 2 or 3 machine opcodes. If you understand how to use STL properly (which includes double-checking your results by disassembling critical points in the binary and inspecting them) you can often get code that is almost as fast as hand-coded assembly. I think that in general, if you use the other main approach to abstraction in C++ (virtual method calls), it's harder for the compiler to crush all of the layers of abstraction down to zero.

      The main problem with C++ templates IMO is that they feel "brittle". It's hard to create large modular programs because of C++ #include dependencies and binary interface difficulties. I think that the best approach for large programs is to identify the performance-critical pieces and code them up in C++/STL as native modules for a nice high-level language like Python, then use the high-level language to glue everything together.

    8. Re:Bloat by vidarh · · Score: 4, Informative
      If you're a C++ programmer and don't use templates, you're not doing your job. If you've ever used map,vector,multimap,set,multiset,list,string,pair or most other classes from the C++ standard library, you've been using templates (yes, even "string" - string is a typedef for std::basic_string).

      You're also being left behind in the dust. Modern C++ is all about exploiting templates to simplify development, and even reduce code bloat (by making it easier to reuse common code) and increase performance (through automatic compile time generation of heavily inlined versions of algorithms).

      If you make a huge template with lots of code that could be easily generalized for all types, then you're writing a bad template: You should factor all common code into a base class and make a template that contain the few parts of the code that are type specific. On the other hand, if your code can't easily be generalized for the types you need, templates save you the tedious and error prone task of maintaining multiple versions of your code specialized for multiple types.

      In that respect templates dramatically reduce the amount of work you need to do, if applied properly.

      As mentioned above, template techniques can dramatically improve performance over a generic algorithm by providing you with an automated way of generating heavily optimized inlined versions of an algorithm. The C++ template syntax is not really ideal for this, but the benefits from using templates for this are tremendous enough to make it worthwhile. Do a search for Vandevoorde's work on expression templates, or for Alexander Alexandrescu on Google to find more, or read Alexandrescu's articles in CUJ.

      Continue to believe your prejudices if you want, but consider that if you can't use or write templates you've essentially shut yourself out of a huge segment of the C++ development job market. I would certainly never hire a "C++ developer" that don't at the very least have thorough experience with the STL, and preferrably understand how to write (and when to write) templates.

    9. Re:Bloat by warmcat · · Score: 2, Insightful
      If you're a C++ programmer and don't use templates, you're not doing your job.
      ...
      I would certainly never hire a "C++ developer" that don't at the very least have thorough experience with the STL, and preferrably understand how to write (and when to write) templates

      As it happens most of my work is done down near the hardware. So those peksy issues of the relationship of compiled code to the hardware - which cut directly across things like having 24 copies of each method in a class because the class is templated across 24 types - are very important.

      Sure for some types of work the longevity and conciseness of the code is more important than the efficiency, I understand that. And in those types of work you can basically forget that you are running on real hardware with real limitations, since time and memory will 'stretch' for you. But just like it sounds you wouldn't hire me, I don't think for my kind of work I would hire you :-)

    10. Re:Bloat by vidarh · · Score: 4, Interesting
      Either the function is generic, in which case, as I wrote, you should write your template properly by using a common base class containing the generic functions, and you won't have 24 copies, you will have one, and your runtime overhead of templating the class (I'm assuming a class, since templating a single function that is already generic enough to cover the types you need is meaningless) both in terms of space and time is exactly nothing - or the function is specific to the types in question, in which case the choice isn't between 24 copies or 1, but between a template or 24 hand written copies.

      Doing work near the hardware is no excuse not to use templates. On the contrary, I'd say that when you work on extremely performance critical code there is one thing you don't want your developers to do: reinventing the wheel over and over for non trivial parts of code - reinventing the wheel is something that's all too often done badly. A well written template will allow you to reuse well written, well tested efficient and small code over and over again for different types and different conditions without that risk.

      Another reason to use templates in an embedded system is that it allow you to easily write reusable components that can be adapted to a particular situation at compile time instead of runtime, opening up reuse opportunities across projects that would otherwise be difficult. This is often done with traits classes or policy classes that allow you to turn on and off functionality of a template at compile time, leaving out any code that isn't actually used.

      In fact, this is an important property of templates in C++: Code that isn't used isn't even semantically analysed, and certainly not included in the generated executable, while the same is not true for members of any class that is externally visible. So you might actually reduce your code size merely by changing some classes into templates even if they don't depend on any type parameter.

      Oh, and I've worked on embedded systems, using exactly the above techniques, including one platform that had 4MB flash and 4MB RAM that we ran Linux on together with FTP and SNMP servers that I wrote (in C++) as well as various other application code, a shell, etc., so I am familiar with how to make C++ code small, and that is one of the reasons I love templates.

    11. Re:Bloat by vidarh · · Score: 2, Informative

      Actually, the C++ standard specifically does NOT require all pointers to be the same size. One of the reasons for this is that not all hardware platforms allow you to directly address every single byte, so that for instance a char pointer might need a pointer to the word a character is contained in and an offset into the word, or similar. The C++ standard only guarantee that all pointers to the same type are the same size.

    12. Re:Bloat by IWannaBeAnAC · · Score: 2, Informative
      Where did you get that idea? You are completely wrong.

      There is no difference at all in performance cost of a template function versus a non-template function. The generated code is exactly the same as if you had explicitly written a non-template function to do the same thing. So there is no performance loss at all due to template. (There might be due to some poor usage of templates, but you could say that about anything, even assembly language!)

      On the other hand, templates allow a style of code that retains some flavour of OO polymorphism while being very fast, as all of the function calls etc are resolved at compile-time. The alternatives are to use dynamic polymorphism (slow), or bloat the source code by manually writing stupid functions like

      void foo_SomeType(SomeType x) { ... }
      void foo_SomeOtherType(SomeOtherType x) { ... }
      ...

    13. Re:Bloat by IWannaBeAnAC · · Score: 2, Insightful
      Removing parts of the library might be a good idea (IOStreams, for example, is pretty slow, for example), and may be desirable in some cases, but the language features you mentioned should not affect performance. One of the design principles (not always kept, mind you) of C++ is that you don't pay for what you don't use.

      If you don't use multiple inheritance, then you don't suffer a performance drop. If you don't use exceptions, you don't suffer a performance drop. Templates, namespaces, and new-style casts all provide the programmer with more tools, and have no intrinsic performance issues while allowing more flexibility of program design.

      In other words, the reason why embedded C++ is so disparaged in the mainstream C++ community is that the subset of C++ it implements is based more around what is easy for compiler writers to implement, rather than what is desirable for a programmer in an embedded environment.

      In some forms of template programming, with some compilers, there is a bloat problem. For the most part, this has been fixed by better compilers (recognising when two different instantiations produce equivalent code) and better design.

    14. Re:Bloat by ucblockhead · · Score: 2, Informative
      Templates are a pretty straightforward trade of space for speed. Given the cheapness of memory these days, that's not a bad trade.

      Though personally, I find little bloat to speak of. It has been literally a decade since I had to worry about memory size. (As opposed to worrying about speed literally yesterday.)

      The largest C++ project I'm working on write now is about 7,000 lines of code. It makes heavy use of both the STL and templates. It runs about 500k on disk and seems to take between one and three megabytes of memory when run.

      --
      The cake is a pie
  4. Re:Are templates always necessary? by Anonymous Coward · · Score: 2, Informative

    Java's everything-inherits-from-Object model is annoying & sometimes rather ugly. There is a vocal group of Java programmers trying to add templates to Java, you should check it out before declaring templates an unnecessary evil.

  5. Re:Are templates always necessary? by FortKnox · · Score: 5, Insightful

    Well, I'm going against my grain here (being a Java lover), but templates mean that you ensure cast.

    For example, I make a stack in C++:
    Stack bleh<int> = new Stack();
    int i = 1;
    bleh.push( i );
    (excuse my syntax, I havne't C++'ed in a few years) and I have a stack full of ints.
    If i use a java container:
    Stack javaStack = new Stack();
    javaStack.push( new Integer( 12 ) );
    I lose cast. If I pop from C++'s bleh, I'm guaranteed to have an int. If I pop from Java's javaStack, I'm getting a java.lang.Object. I have to force cast and have a chance of a runtime exception.

    That is one major reason why templates are a good thing.

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
  6. Professional Computing Series by Anonymous Coward · · Score: 2, Informative

    Is this another book in their Professional Computing Series?

    I've found several of them that I've read to be excellent references. They aren't textbooks, but they contain lots of information that is accessible and useable to people who write lots of code and want it to be understandable and maintainable.

  7. What about Java/C++ developers by Gortbusters.org · · Score: 2, Interesting

    I know a lot of people who are required, for their job, to write both Java and C++ code. Are templates really applicable to those developers? In other words when you switch back and forth between the two frequently do you resort to the lowest common denominators of the language instead of using more "advanced" aspects?

    My J-Developer friend was just telling me the other day how he longed for templates in Java.

    --
    --------
    Free your mind.
  8. Re:Are templates always necessary? by J0ey4 · · Score: 5, Informative

    You are forgetting one of the biggest advantages to generics such as templates, speed. When templates are used much if not all of the binding is accomplished statically at compile time, when inheritance is used much if not all of the binding occurs at runtime. When you use inheritance every call to a virtual method requires a lookup to the vtable, this overhead is non-exsistent in templates. This is not an issue if you are writing bloated desktop apps in Java, but embedded or system-level applications demand the highest speeds possible.

  9. Re:Are templates always necessary? by TechnoVooDooDaddy · · Score: 5, Funny

    a fairly well thought out, educated, concise, relevant comment on the article..

    WHO ARE YOU AND WHAT HAVE YOU DONE WITH SLASHDOT!?

  10. Re:Are templates always necessary? by fredrik70 · · Score: 2, Interesting

    yeah, but then you would have to do all this awful casting everywhere as you have to do in Java. TEmplates is a much more elegant solution IMHO.
    Java is supposed to have templates from 1.5 anyway IIRC, so you'll have a choice then.

    --
    if (!signature) { throw std::runtime_error("No sig!"); }
  11. Re:Are templates always necessary? by ChaoticChaos · · Score: 2

    A post like your's is the reason I posted. I wanted to see some varying opinions on the subjects. Thanks for falling into my trap. LOL!

    1) Why do you find Java's object model annoying/ugly?

    2) Why in the world would a group of Java programmers want Templates added to the language? It's easy to find out what Class an object is in Java. I never have typecasting issues.

  12. Re:Are templates always necessary? by SquareOfS · · Score: 5, Informative
    Umm . . . not sure if we're missing the point here but:

    One of the major strengths of templates is to avoid exactly the situation that Java everything-from-Object inheritance causes in collections.

    In other words, this code:

    MyObject m = (MyObject)iterator.next();
    gets boring really quickly. Templates in collections saves you all that downcasting.

    In fact, it's so useful, it's appearing in Java in JDK1.5, courtesy of JSR 14.

    But far beyond convenience when typing, the important point is that using templates or generics in collections turns the typesafety of collections into a compile-time check rather than a runtime exception. Which is a Good Thing.

  13. Re:Are templates always necessary? by fredrik70 · · Score: 3, Informative

    check out this extension:

    http://www.cis.unisa.edu.au/~pizza/gj/

    --
    if (!signature) { throw std::runtime_error("No sig!"); }
  14. Only when misused by DreadSpoon · · Score: 2, Insightful

    Templates are only bloat when misused. In many cases, your options are to write a template, or cut-and-paste then modify a class/function over and over. You can also write classes that only have template members, so if most of a class is the exact same no matter the data type, you're fine. Templates also let you do things you simply can't do in this low level of a language otherwise (and many high level languages also don't allow) - take a look at what the BOOST library does. There comes a point when you have speed/efficiency/code-size vs. taking 6 years or 6 weeks to code something, and with today's hardware, the later is usually the best choice. Also, templates can be used to generate data, not just code, so where you might have before needed a function call in order to compute a value, a template could turn it into the actual value at compile-time (look at how modern games use templates to generate sin/cos/tan/etc. values for constant inputs).

  15. Re:Are templates always necessary? by FortKnox · · Score: 3, Informative

    I should have completed my thoughts before posting.
    I wanted to conclude that the only way to ensure cast with java's is either
    A.) Write a wrapper around the collection/map (where the accessors cast to the object, eg:
    public void setStack( Integer input )
    ).
    B.) Use arrays

    The big downfall of java.lang.Object is unsure cast (so you have to be careful with your coding, and follow good polymorphic code styles).

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
  16. Re:Are templates always necessary? by lazyl · · Score: 3, Informative

    You imply that inheriting from a base class is always better, but that's not necessarially true.

    The guy(s) who wrote the STL Containter Classes did it that way (using templates) because they think it's better than having all the objects inherit from one base. It's a style of programming called Generic Programming.

    The basis of Java is dynamic run-time polymorphism. Using templates and generic programming techinques most run-time polymorphic algorithims can be reimplemented using compile-time polymorphism, which is much faster. That's what the C++ STL container classes are. That's where the power of templates are.

    p.s. I've looked at the book in the article and I would describe it as an entire book of special cases. It explains things like recursive template definitions. Things that are so confusing that I try and stay away from most of them. They make code un-readable to anyone but a template expert. Then again, I don't write templated libraries either.

    --
    Aw crap, ninjas!
  17. Re:Are templates always necessary? by FortKnox · · Score: 3, Interesting

    If the only thing you're ever pushing on the stack is an Integer, then there is no risk of error from casting back to Integer when you pop off.

    But you can't be absolutely sure. Yes, in practice, we generally assume everything is ok, and we rarely have trouble, but when you get down to reuse things can get hairy (hey, the compiler isn't stopping me from adding my String into the Stack, so why not?).
    The nice thing about Java to counter, though, is reflection. You can always check the class type and methods before casting.

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
  18. Re:Are templates always necessary? by ChaoticChaos · · Score: 2, Interesting

    This ultimately comes down to a decision of *when* do you want to handle the "type" issue.

    In Templates, you decide up front.

    In Java, you handle the decision when you actually use the java.lang.Object object. In your example, adding the simple "if" check with the code ".getClass().getName().toLowerCase()" to determine you're truly using an Integer would eliminate any runtime errors whatsoever.

    I have never had a Java runtime error over typecasting issues. If something unexpected is in the Container, I throw an exception or bypass the value entirely. There is no excuse for having a typecasting issue in Java when you can check the object's type.

  19. Re:Are templates always necessary? by truth_revealed · · Score: 4, Insightful

    Templates only seem to be a necessary evil in OO languages that don't ultimately inherit all objects from one object.

    This is a naive view that circa 1992 C++ collection class designers used to share. The OO-container strategy was proven to be slow and not type-safe. The designer of the C++ Standard Template Library (STL) Stepanov does not even believe in OO programming - he calls OO a hoax. I personally would not go that far, but I appreciate that OO and generics are completely independent concepts. Furthermore, an STL map or vector working on types directly is much more space efficient than any OO container-based approach because each object contained does not require OO overhead. Indeed, native types (ints, doubles, etc) in vectors can be nearly as efficiently stored and accessed under STL as would C style arrays. No need for awkward casting or unnecessary and slow boxing/unboxing. To sumamrize, C++ templates and the STL fit in perfectly with the C++'s "zero overhead" principle.

  20. Templates are the best C++ feature imho....BUT... by fcrick · · Score: 4, Interesting

    Microsoft just doesnt't compile them properly and it is very frustrating to all C++ programmers. Chances are, if you write C++ in the commercial world, your company has the very wise policy of making sure you stay roughly within the capabilities of the most popular compilers. This basically means you can use STL's vector, string, and list, and a pretty small collection of others. This, in my opinion, is a programmer's tragedy.

    Utility C++ templates allow it to create and use some amazing things. I personally rarely write anything but the most simple ones, but when I'm allowed, there are huge libraries of amazing template classes. I learned ML at some point, and I remember the wonder when I happened upon the tuple template class for c++. With the exception of the fact you are forced to carry the type around (as a typedef of course), it works exactly like an ML tuple, a tool I came to love in my short time with ML. Someone simply wrote the template, and it was in C++ too! (a tuple is like an STL pair, but has an arbitrary number of members, set on construction).

    Of course, even VC7 doesn't compile it. If you work at Microsoft in the Visual Studio area, PLEASE tell them to get standard compliant already! Yeah yeah templates can be slow to compile, but give us the option at least!

    --
    Your signatures belong to me.
  21. Templates and Linked Lists.. by Shant3030 · · Score: 2, Interesting

    Being fresh out of college, we used linked lists like they were going out of style. When I began work, I found out they were! Using an STL template and container serves as a good replacement for linked lists and other annoying data structures. I rarely use arrays anymore, I would rather use a vector or map. my personal preference, maybe because I hated linked lists and malloc arrays we exhaustively used in college.

    --
    100% Insightful
  22. 3D Math by devnull17 · · Score: 2, Interesting

    There is an interesting use for templates in 3D vector math:

    http://www.flipcode.com/tutorials/tut_fastmath.sht ml.

    It's a kludge, but it provides some real performance benefits.

    1. Re:3D Math by Minna+Kirai · · Score: 2, Insightful

      It is by no means a "kludge". The intended use of a tool is never a kludge, even if some people find it personally unintuitive. (The only kludgey thing in that article was the extra magic needed to convince MS VC++ to deal with templates sanely)

      The goal of adding templates to C++ was to provide the same power macros provided to C, but as part of the language, rather than a preprocessor to it. That way, they can be typesafe, produce better error messages, and be more flexible (since templates live inside of namespaces, unlike macros which exist at the parser level).

      C programmers often performed fast math evaluations with macros, so replacing them with templates is simply a natural step.

      However, looking at templates from an entirely different perspective- it is possible to reasonably classify most all uses of templates as "kludges".

      Why? Because they are often used to force an evaluation to happen at compile-time, rather than runtime. But, if compilers made full use of the static program information that is present during compilation, they could determine that many conditional checks are often tautologies, and elminate them from the output code.

      The reason C++ compilers can't usually make these throughout checks is because of backwards compatibility- to support interoperation with other programming languages, individual C++ files are compiled independently and then linked together by a stupider program. The linker has little knowledge of the static program elements, and less ability to modify the output code. So many potentially useful optimizations are impossible- unless the programmer uses something like templates to force them to occur.

      So, from that perspective, it can be argued that nearly every template is a kludge- a workaround for the legacy compiler/linker split. (Many uses of macros were a similar kludge- a way to force an expression to be computed inline, rather than spending a function dispatch on it)

  23. One other point by biglig2 · · Score: 3, Funny

    Can I just point out that as well as people who don't program in C++, "C++ Templates: The Complete Guide" will also be of limited interest to those who can't read, as well as those who can but read only Cantonese, not English. It is of limited use for those looking for a guid on changing the timing belts in '98 Pintos, and as a guide to the wines of the Alsace region it is sadly lacking. Dr Aloquin Samovar reports from the Naval Hospital that the book is not suitable for use by transplant surgeons as a temporary heart.

    --
    ~~~~~ BigLig2? You mean there's another one of me?
  24. No bloat if you design correctly. by Chemisor · · Score: 5, Insightful

    Just like macros can bloat your code, so can templates. If you put "real" code in templates, it will be duplicated; however, consider that you would have probably had to write it anyway, and having template instances is FAR better than having cut-n-paste code. STL instances can get pretty big because they have lots of memory management code in there and type-specific operations; this is good because it gives you type safety and proper element assignments. You can implement it another way, but you have to sacrifice something. Either it is type safety (like Java does with its containers), or correct element handling (escuse the shameless plug for my own ustl library).

  25. Re:template versus derivation by jbert · · Score: 2, Informative

    [and here's that once again with feeling (and better HTML)]

    OK. Could someone please offer some informed comment on the following. (thanks in advance).

    If I template a two-argument function in C++ to (e.g.) compare two instances of a class for equality (using the == operator) and print them to an ostream if they fail to match (using the &lt&lt operator) [why yes, I was writing some unit testing infrastructure, why do you ask?] then:

    - my template function will fail to compile if called with two instances of objects which lack the == and &lt&lt operators.

    - this is a broadly equivalent approach to defining a virtual base class (java interface) requiring implementation of these two operators and re-writing the template function to take pointers to the relevant base class. Users would need to derive from my base class to call my function (and hence would have to implement those two operators).

    The latter approach (derivation) is more coding for the caller.

    The former approach (templating) requires the coder to inspect my entire template function (or read the Fine Docs) to determine the interface s/he needs to implement to use it.

    Both approaches are compile-time type safe.

    Given that the two approaches are in some sense equivalent, are there good guidelines on when to use derivation instead of templates or vice versa?

    PS. The equivalent for the STL would be that the list&lttype T&gt template was actually a class which manipulated objects which derive from a "Listable" interface.

  26. No portability info? Bummer. by baxissimo · · Score: 4, Insightful
    As it is, it doesn't even deal with differences between C++ implementations - it doesn't even list GCC in the index.

    That's too bad, because 9 out of 10 times when I've had troubles with templates it's because of differences between C++ implementations. Beautiful, well thought out, intricate standards-compliant examples are useless if I can't actually get them to compile with my real-world compiler!

    The book I'm looking for is the one that gives me real-world recipes for getting around bone-headded compilers. For example, there are at least 3 different ways to declare templatized friend functions depending on the compiler. Only one is correct according to the standard, but the standard isn't worth a whole lot to me today if the compilers I'm stuck using don't follow it. And likewise, an advanced templates book isn't of much use to me today if the examples won't compile on my compilers.

    1. Re:No portability info? Bummer. by Anonymous Coward · · Score: 2, Informative

      (I wrote the book, so I'm hardly objective.)

      We didn't include many references to specific compilers because version change so quicly.

      However, we do point out various shortcomings of compilers (without naming them) and, when feasible, we present alternative programming techniques to work around the limitation. It's certainly not the main emphasis of the book, but you'll find such things sprinkled throughout.

  27. An excellent book, but be aware by dsplat · · Score: 4, Informative

    First, there are some significant errata (and a lot of minor typos). Get the errata list and the code for all of the examples from one of the authors at his website. Second, some of these techniques depend on features that aren't yet available in many compilers. Don't expect them all to work yet. They do discuss that in the book.

    With that said, I'm not sure that I would have rated this book a 10, but it's close enough that I'm not arguing. It is not a light read, nor should it be. This book and Andrei Alexandrescu's Modern C++ Design have convinced me that C++ templates are much more powerful, useful and complex than I realized. In fact, if I hadn't read Alexandrescu's book first, I wouldn't have thought C++ Templates was missing anything. These two books should be on the shelf of anyone who wants to use the full power of templates.

    --
    The net will not be what we demand, but what we make it. Build it well.
  28. Re:Are templates always necessary? by FortKnox · · Score: 2, Interesting

    I already conceded this point somewhat in another reply.

    Its not that I always have trouble with it, its more when dealing with another persons code and reuse that you are never sure.

    BTW - Using "instanceof" is a lot easier than ".getClass().getName().toLowerCase()". Even easier would just be to catch the ClassCastException, report it (or swallow it), and go on (or get the next value).

    --
    Good quote, too many chars. Seriously, the slashdot 120 char limit sucks!
  29. Re:Templates are the best C++ feature imho....BUT. by dalleboy · · Score: 2, Interesting

    Name one compiler that is 100% C++ standard compliant.

  30. Re:Are templates always necessary? by bunratty · · Score: 3, Informative

    GJ is the old implementation of Java Generics. It has since evolved into JSR-014. Sun has a prototype implementation of a compiler that supports generics, and there's even an entire forum for discussing Java generics.

    --
    What a fool believes, he sees, no wise man has the power to reason away.
  31. The problem with C++... by jackjumper · · Score: 2, Interesting

    IMHO, is that a book like this needs to exist. Templates are *way* too complicated for something that is supposed to reduce complication.

  32. Closures with tamplates by fdicostanzo · · Score: 2, Interesting

    I rarely see this in template discussions but the thing I love about templates is the ability to do template "closures" for lazy evaluation whereby instead of returning the result of a function, you return an object which represents the application of the function to those arguements. This object then gets cast into the final resultant object.

    Why?

    Lets say you are concatenating a bunch of strings. Normally, you would create the concatenation of two strings, then concatenate the third, etc. Depending upon your string implementation, you could reallocate the string results many times.

    However, with template closures, the concatenation would return an object which pointed to the two objects that were to be concatenated. Then the second concatenation would point to that object plus the next string. When the entire object was finally actualized by, say, setting it to a variable or as a function argument, then it would create the final string. It could then gather the lengths of all the strings, create a single result string, and then copy everything into it.

    And it wouldn't look any more complicated than:

    string a = b + c + d + e;

    or whatever and it would still be optimally efficient.

    The big downside is that error messages are all but useless.

    --
    Synergies are basically awesome, and they're even better when you leverage them. -PA
  33. Re:Templates are the best C++ feature imho....BUT. by Eponymous+Coward · · Score: 2, Informative

    Greg Comeau's is pretty damned good. Any compiler built off of EDG's (Edison Design Group) stuff is going to be compliant (including the export keyword)

  34. Re:Are templates always necessary? by bunratty · · Score: 3, Informative
    The nice thing about Java to counter, though, is reflection. You can always check the class type and methods before casting.
    It's almost always better to avoid reflection than to use it. In this case, an instanceof test will be easier and faster. Example: Quick, write this code using reflection instead of instanceof:
    if (x instanceof Number) {
    Number n = (Number) x;
    // ...
    }
    Now time how much slower it is...
    --
    What a fool believes, he sees, no wise man has the power to reason away.
  35. Extensive template use is dangerous by mcgroarty · · Score: 4, Insightful
    Despite C++ templates having been around for quite some time, development environments still haven't caught up.

    Debugging heavily templatized code is thoroughly nasty. Names are mangled beyond recognition for anyone not using a 500 column display or lots of scroll bars. Stepping through code in the debugger often yields senseless results -- you often cannot see the source for the instructions being generated without manually tracing through the headers and looking for every overload and template body declaration. Templates thorougly ambiguate linker symbols. Templates slow compiles to a crawl, often adding tens or hundreds of thousands of lines to every inclusion of a given header in order to define the types it uses. With subtly improper use, templates can bloat code size astronimically and create horrendous execution bloat.

    I don't know how many weeks I've lost to helping others debug or rewrite their code because they thought they would do something "clever" with templates and they ended up creating a maze. And bringing in third-party code with templatized interfaces has frequently required more time to debug and adapt than it would have taken to create the code anew.

    If you're going to use templates, stick to simple container classes for now. Anything else should be considered theoretical research until the tools catch up. Let me repeat: development tools HAVE NOT CAUGHT UP WITH C++ TEMPLATES. There is no debugger available which makes templates as transparent as normal code, inline functions or even #defines.

    And please save your first forray into templates for private projects. Don't inject your template experiments into code others are trying to use!

  36. Re:What I want explained to me... by rudedog · · Score: 3, Insightful

    about templates is why this doesn't work:

    main.cpp has never seen the implementation detials of the Foo constructor or the getFoo method, because g++ compiles each compilation unit in isolation. Conversely, no real code actually got generated when g++ compiled Foo.cpp, because that didn't contain a particular instantiation of a template, only the generic template definition.

    The typical idiom is to put a '#include "Foo.cpp"' at the bottom of Foo.h. Then, when g++ compiles main.cpp, it will have seen the template's implementation in order to turn it into code.

    This actually is explained in the book in question (chapter 6, I think).

  37. Re:Are templates always necessary? by dabuk · · Score: 2, Informative

    There is no reason why you can't have multiple inheritance if everything inherits from a single base class.

    C++ might have problems because it would have to use virtual inheritance which probably hurt performance. Eiffel has a base class called ANY which is like Java's Object class. So you can declare lists like LIST[ANY] if you want, but it also has genericity allowing you to declare your list as LIST[INTEGER].

  38. Re:What I want explained to me... by Lethyos · · Score: 2, Insightful

    *nod*

    You can get round this by putting the entire template definition in the header file, which may lead to massive code bloat if your linker doesn't combine all the multiple definitions.

    That is essentially #include "Foo.cpp", which is insanely ugly. Come to think of it, it's been so long since I last tried to use that I cannot remember exactly what I was trying to do with it -- except that it would have made things a lot easier. :-)

    As far as I can recall (without getting into specifics), I had a limited number of classes that while they were similar in nature, did not necessarily lend themselves to inheritance from a super class. Overloaded operators were present to make them act appropriately in an encapsulation (that would be class Foo).

    A more basic example would be a graph implementation. The first time I wanted to do this was for course work. I tried creating a generic node object that could take any types for the key and data, and this is how I approached it (should be fine especially since the node class would have no need to manupulate the data).

    Professor said that this approach created ambiguities, but with a concrete instantiation, I thought the compiler/linker would be able to work it out. Oh well.

    I like how Java has an "Object" superclass to everything. That's solves this issue. As for C++, I guess it's not so bad to have an "Object" class in your project.

    --
    Why bother.
  39. Templates are a crutch by pclminion · · Score: 4, Interesting
    Templates are a crutch. So are overloaded operators, overloaded functions, public vs. private data, etc. A crutch is simply something which makes it easier to accomplish a goal. A crutch, by itself, is not a bad thing.

    However, it's nearly always fatal to mistake a tool (in this case, templates) for an end in itself (a functioning, maintainable codebase). No programming technology, be it HLL in general, objects, inheritance, or even templates will replace the need to think intelligently and make sound engineering decisions. You cannot build a skyscraper without the proper knowledge, no matter how excellent your hammer is.

    The company I work for is among the few remaining who produce large-scale Windows products written entirely (ok, 99.9%) in C. My work is in a totally different world than the object oriented people, yet I still manage to accomplish everything an OO programmer could do. The secret here is not cute little language features, but discipline and correct design.

    IMHO, templates do not deserve a book quite this large. Clearly, the author has had enormous experience in various situations, and knows how to solve all kinds of problems with templates, BUT -- remember the famous words passed down from people wiser than ourselves: "When all you have is a hammer, everything starts to look like a nail." Make sure the hammer isn't the only thing in your toolbox.

  40. C++ Template Strength by Lailyx · · Score: 2, Interesting

    For those not too familiar with templates (personally I learned all from Stroustrup's book), there are a lot of interesting and sometimes quirky features.

    One of the best examples perhaps is the STL vector class, which has three implementations. An implementation for a vector of booleans (made specifically to save space), a vector for any type of pointer, and then the generic vector class that covers anything else. Templates have some powerful features.

    Unfortunately, there's still some things that need to be done in the compilers. Certain compilers in the past have had problems with them (hopefully they're fixed now), and errors in templated code are cryptically reported -- which always confused me. If compilers mangle a name to get the templates to compile, why can't they unmangle the name when reporting errors?

    ------------------
    Lailyx -- Karma's overrated.

  41. Re:What I want explained to me... by gwappo · · Score: 2, Informative
    Reason this doesn't work is due to templates working at compile time, and you specify use at linkage. The linker is fully template-ignorant and uses decorated names based on the template instantiation to match up templated code much like they were normal C-style functions.

    So, in other words, while your compiler is chugging along on Foo.cpp - it treats your template functions as Declarations, and won't instantiate the code until it knows what this code should look like (and it won't know this until parameter T is defined!).

    Depending on class T (in this case an int, but say it's something that overloads the assignment operator), the implementation will be made.

    "Doesn't a .h cause bloat in instances of Foo for each .cpp that uses it?"

    Putting this in the header file would cause bloat, but only in your .o/.obj files since the linker will only pick one instance of your templatized Foot and use that to link, the others are ignored

    (much like you can override the library malloc (or any other function) with your own, should you be so inclined).

    "So why don't linkers get smarter"

    Because if you were to put templates in your linker, you're actually postponing compilation into the linker -- in other words, you're doing away your linker and building one compiler that treats everything as "sort of" an include file.

    Still do-able, but problematic for larger projects of a couple of hundred/thousand files.

    Hope that answers the question.

  42. templates are not just for fancy containers by Anonymous Coward · · Score: 2, Interesting

    It is tempting to think of templates as just a fancy way to make a list of addresses (i.e. list) without having to do any casting. But templates let you do much, much more than that- It adds another tool to the programmers' arsenal by allowing him/her to decouple different parts of a program in order to improve its design. This new technique is called "Generic Programming" and C++ programmers like to think of it as being "orthogonal" to other ways of programming.

    The first dimension of program design is to break code into procedures that can be called from several different places cleanly and transparently. This is what C and procedural programming made possible.

    The second dimension is to have a type system that can channel the program to the correct code indirectly, either dynamically through OO polymorphism or statically through function overloading. This was what object-oriented programming and early C++ made possible.

    The third orthogonal dimension is generic typing, or templating- Using this technique, new computer code can be created in a safe manner during compile time that allows abstractly-written pieces to be stuck together arbitrarily as needed to generate new code. All of these pieces have to fit perfectly in order for the compiler to accept it. If the pieces don't fit together perfectly, the programmer has many types of "glue" available (such as function adaptors, or iterator adaptors, etc.) to make them fit perfectly. If the glue isn't 100% perfect, the compiler lets you know and you can correct it. It can be a beautiful way to program if done correctly!

    It also lets people program in a "functional" style, which was originally invented by LISP programmers, and is a great way to glue together abstract objects with abstract alorithms, without having many unsafe local variables. An example is "currying", where a function taking two parameters can be changed to require only one:

    int multiply(int a,int b)//a function that multiplies two numbers
    {
    return a*b;
    }
    int(*x)(int)//x is a function that accepts only one number!

    x=boost::bind(&multiply,2,_1);//set x equal to a newly created "version" of the multiply function that requires only one number- A function requiring 2 numbers now only requires one, without a local variable needed!

    int y=x(3); //y is now equal to 6

    Another functional programming principle that is now possible is to write all your functions to use iterators, which are basically pointer-like objects that can point to anything: lists, arrays, stacks, almost anything! So to multiply all numbers together in an unknown(!) data structure you can write:

    templatemultiply_all(T i,T iend) //i and iend are "iterators"
    {
    T::value_type x;
    while(i!=iend)
    x*=i++;
    return x;
    }

    If you begcome comfortable with thinking of all your data manipulation tasks in terms of iterators and use templates, a whole new world of programming techniques opens up to you!

  43. Re:template versus derivation by vidarh · · Score: 2, Informative
    I don't really see your particular case as a problem - as you say it is already typesafe, and so a comment at the top of your function "requires type Foo to support interface Bar" would serve the same purpose as what you suggest.

    However if you want more user friendly compiler error messages, that's another matter. A lot of work has gone into "compile time asserts", to catch as many problems as possible at compile time and give more intuitive errorts (in this case you got an error, but consider the problems if the classes supported the operators you needed but made them do something entirely different).

    Instead of deriving, you could for instance check for an enum "supports_someinterface" in the types using a standard assert.

    This allow you to use "assert(Foo::supports_interface_Bar);" in the functions that have specific requirements. Note that the value of the enum is irelevant as long as it's non-null, and since the enum is a constant value known at compile time, there should be no runtime overhead (neither space nor performance) of the assert at all if your compiler is reasonably smart.

    With GCC, this gives me the reasonably friendly error message: "'supports_interface_Bar' is not a member of type `Foo'" instead of (or rather, in addition to) some hopelessly cryptic error message if I try to instantiate a template with the above assert on a type that doesn't have the enum.

    Of course, you might not have the luxury of changing all types you might want to use with your template, and some of them may already fulfill the requirements even if they don't contain the enum.

    Fear not, that's what traits are for. Declare a template. Specialize the template for any type that supports your interface, and instead of "assert(Foo:supports_interface_Bar)", you might do "assert(Supports<Foo>::interface_Bar)" or "assert(Supports<Foo>::requirement_HasOutputOperat or)".

    Strategically placing these at the top of your functions also serve to document the requirements.

    Ok, so I saved the simplest option for your case until last (the above is better suited for complex requirements, not something as simple as "this templates needs member functions A,B and C to be implemented) :

    assert(&Foo::operator<<)

    With GCC, this produces the error message "`operator<<' is not a member of type `A'" if the operator isn't supported. Place asserts covering all the member functions you need at the head of your function and you both have documentation and reasonable error messages.

    The above should have no runtime cost at all provided that the compiler at compile time is willing to guarantee that Foo::operator<< will never occupy address 0. However, don't assume your C++ compiler that smart (GCC 2.96 doesn't appear to be, I haven't checked any newer versions), so one improvement: "assert(sizeof(&Foo::operator<&lt))". sizeof is evaluated at compiletime, resulting in a constant that in this case must be non-null, meaning the assert will neven trigger, meaning the compiler will discard the code (this was enough to make GCC optimize the thing away).

    This leaves us with this nice little macro (who I'm sure someone will find a nasty problem with :-):

    #define REQUIRE_MEMBER(expr__) assert(sizeof(&(expr__)))

    Which can be used like this:

    REQUIRE_MEMBER(Foo::operator<&lt);

    Hot tip: sizeof() is extremely versatile for compile time testing whenever you can reduce the problem to either making code illegal in one case or return a constant expression (which is needed to apply sizeof to it), or when you an reduce a problem into a constant expression that will be a different size (that you can compare with a known quantity) depending on the outcome.

    The book being reviewed contains at least one good example of this.

  44. Standard C++ with STL is the best abstract machine by CodeArt · · Score: 3, Interesting

    If you want to be able to recognize what is the truth and what are lies (more lies) with Sun's J2EE and Microsoft .NET proprietary frameworks (however, they have and will have place in computing) study Standard C++ with the STL. Just reading Bjarne Stroustrup's interviews you will avoid shortsightedness and you will learn much more about computing then reading anything else.

  45. Re:Bloat: O.K., I'll bite by renehollan · · Score: 4, Informative
    Templates can certainly lead to code bloat: you're telling the compiler how to generate classes (and, by extention, member and non-member functions) that are parametrized by type.

    So, instead of void Sort(int array[], size_t count) { ... } to sort an array of ints, you have template <typename T> Sort(T array[], size_t count) { ... } and the means to define a function that can sort an array of anything, with complete type-safety. Naturally, this generates a Sort function for each kind of array of things you need to sort... hmmm, there's room for improvement, no?

    If you don't get the "there's room for improvement" part, and use templates to get nice type-specific varients of common functions, you will get code bloat, and that is one of the things that give templated-code a bad reputation. But, we're Slashdotters, we're smarter than that.

    Recalling our C days, we immediately code void Sort(void *array, size_t count, int (*compare)(void *, void *)){ ... } where we pass a generic array pointer, and an additional pointer to a function that knows how to compare generic elements -- the specific call will then be something like: Sort((void *)pFoo, count, (int (*)(void *, void *))FooCompare). Gee, where did all our typesafety go? [Java programmers who are otherwise typesafety puristis grind their teeth at this point].

    If you can imagine a generic implementation, you can combine the best of both approaches: hiding the type downcasting inside the generic templated definition:

    inline void template <typename T> Sort(T array[], size_t count)
    {
    genericSort((void *)array, count, (int (*)(void *, void *)SortCompare<T>);
    }

    and for every array of type T you need to sort, define a int SortCompare&ltT&gt(T *arg1, T *arg2). (You could, alternately still pass that function to the generic sort routine, if you had different comparison functions for the same types of data (say, case-sensitive and case-insensitive sorting, or lexicographic vs. ASCII text sorting, etc.).)

    Note the inline declaration. This lets a smart compiler code the call to the generic function inline, avoiding a double function call. In practice, if the only thing you are doing is some type casting, no additional code is generated.

    So, you still have the potentially dangerous downcasting, but you've encapsulated it inside a template definition, relieving the application programmer to have to worry about it. Does all this mean extra work? It sure looks that you have to come up with a generic implementation and then make a nice and pretty templated type-safe wrapper around it.

    This is true, and well worth the effort for code that has to be robust and easy to use, particularly by others. Library writers know this rule all too well.

    Of course, in a pinch, or when a generic implementation is not obvious, or known to be non-existent, or when a particulary implementation exists for some types of objects, you can punt and let the compiler generate multiple instances of type-safe code, without a generic back-end implementation, accepting the code bloat that results.

    In the end, it becomes a matter of compromise and wise design decisions. Unfortunately, with choice, comes the effort to chose, and to chose wisely. It is the unwise use of templates that leads to their sometimes ill-deserved "code bloat" reputation. One of the differences between the skilled and less-skilled programmer is the ability to make these choices correctly and quickly, leveraging the language features that let the corresponding design decisions be put into practice.

    Other related C++ topics would include the notions that "multiple inheritence leads to slow code," "exception handling and run-time type information have high overhead". Again, one has to weigh the advantages offered by these techinques against the skill needed to use them wisely, and the performance penalty paid. I'll let someone else chime in now.

    --
    You could've hired me.
  46. This review isn't very good by IWannaBeAnAC · · Score: 2, Interesting
    I don't understand the comment about examples. In the early part of the book, it is true that many of the examples are rather generic, but adding another set of more concrete examples would bloat the book, and would be completely unncesessary IMHO. They are easy enough to understand as it is (with well thought-out identifier names etc.)

    Later in the book, on template metaprogramming etc, there are lots of concrete examples. Perhaps the reviewer didn't read that far?

    True, the book deals exclusively with C++. But contrary to what the reviewer states, it deals extensively with differences in C++ implementations. Whether or not one particular C++ compiler is listed in the index is not a very good judge!

    Reading his last paragraph, I am sure now the reviewer did not read all of the book. It is not written in "cookbook" style, but for sure everyone reading the book will learn and discover new ideas for template design that they didn't know before. And the capabilities of parametric polymorphism are explored in detail, with quite large sections on how they could be extended (and possibly will, in the next C++ standard) to make some types of programming easier.

    In short, this book is a mix between an academic treatise (it encapsulates practically all that is currently known about the C++ template mechanism), and practical guide to writing your own templates.

  47. Spirit - a lex/yacc written in C++ templates by truth_revealed · · Score: 2, Informative

    Spirit has to be seen to be believed. Basically you contruct a parser which looks like normal extended Backus-Normal Form (EBNF) but the source you write is 100% C++ source code - not run through a preprocessor:


    struct calculator : public grammar<calculator> {
    template <typename ScannerT>
    struct definition {
    definition(calculator const& self) {
    expression = term
    >> *( ('+' >> term)[&do_add]
    | ('-' >> term)[&do_subt]
    );
    term = factor
    >> *( ('*' >> factor)[&do_mult]
    | ('/' >> factor)[&do_div]
    );
    factor = lexeme_d[(+digit_p)[&do_int]]
    | '(' >> expression >> ')'
    | ('-' >> factor)[&do_neg]
    | ('+' >> factor);
    }
    rule<ScannerT> expression, term, factor;
    rule<ScannerT> const& start() const { return expression; }
    };
    };


    This is truly a testimony to the power and expressiveness of C++ operator overloading and templates.

    As an aside, Perl6 is slated to have lexer/yaccer rule syntax built into the language itself. It's really an exciting time for users of computer languages.

  48. Genetic programming by iamacat · · Score: 2, Funny
    Wouldn't this be a good term when someone is thinking about programmers gender or race when reading a technical article?

    I use she because women (and some men!) get all offended if I use "he" as a generic pronoun. I couldn't care less myself, so fine, have it their way. Besides... ladies first! At least when it's this easy. I don't think most people have mental images of every word they say/hear. Otherwise, how can you stand walking around at work hearing things like "you screwed my PC", "this code kicks ass" and "I have to remove all the bugs from this piece of shit today"?

  49. Re: Are templates always necessary? by netjeff · · Score: 2, Informative
    SquareOfS wrote:
    But far beyond convenience when typing, the important point is that using templates or generics in collections turns the typesafety of collections into a compile-time check rather than a runtime exception.

    Templates in C++ go much beyond typesafe collections. As an earlier poster commented, in technical circles it's referred to as "parametric polymorphism". For the layperson, you can think of it as a form of specialized code generation.

    The best example of how much bigger they are than typesafe collections is the use of templates for traits and policies. Take the classic reference counted smart pointer, which usually looks like this:

    SmartPtr<int> i_sp = new int(5);
    cout << *i_sp << endl;

    What about the question of whether SmartPtrs should be allowed to hold null pointers? Maybe in some case it's appropriate, but in others an exception should be thrown if it's attempted. Rather than having two different SmartPtr implementation, you add a new template parameters, the OwnershipPolicy type. The SmartPtr author than provides types like AssertCheckStrict and NoCheck. So then your code looks like this:

    SmartPtr<int, NoCheck> i_sp = new int(5);
    SmartPtr<int, AssertCheckStrict> j_sp new int(6);

    This example comes from Alexandrescu's Modern C++ Design, and his Loki framework.
  50. Re:Are templates always necessary? by ucblockhead · · Score: 3, Insightful
    The difference becomes clear if you accidently try to push something else on the stack. If you try to push a string onto the STL stack, you get a compile error. If you try to do the same to the Java stack, you don't find out until runtime, when you do the cast.


    In other words, you better hope that your testing is good and that the bug that causes a string to get put on the stack doesn't only appear in a rare set of conditions.

    --
    The cake is a pie
  51. Re:Are templates always necessary? by jaoswald · · Score: 3, Interesting

    This whole compile-time vs. run-time error business is a red herring.

    When you say getting an error at compile-time is better, you are just saying that C++ ensures that your program fits in the straitjacket that you made for it, ignoring the fact that you've made a straitjacket in the first place!

    Making a stack which is "int only" is totally specialized. How are you "accidentally" going to write code that asks for something else, if your problem is so focussed that it only needs ints?
    You really think that using strings by mistake is going to be a major source of bugs?

    The real problem is that C++ operations are type-specialized at compile time. C++ compilers, for instance, don't know how to add numbers unless they know the type at compile time. In a dynamic language, the addition operator knows how to add whatever numbers it sees at run-time.

    For every set of bugs that a compile-time error catches, there is a corresponding set of desirable program behaviors that become more difficult to explain to the compiler. That's why the whole idea of "design patterns" caught fire in the C++ world. These design patterns are like a phrase book translating your desire into the C++ language. If you have a more flexible language, you don't need a phrase book as often!

  52. Re:Are templates always necessary? by Old+Wolf · · Score: 2

    If you're writing production code then you don't want weird exceptions throwing up all over the place. I'd far rather make the straitjacket I want and then keep to it, than have a higher risk of my program barfing.

    For example, with the Stack cast to int before - what if the stack definition is somewhere over the other part of the program, and one member of the team decides it should be a stack of vectors (or something), and your code to pop an int is in a very rare situation (so it may get missed in blackbox testing) ?

  53. Re:Yes. Templates are not macros by Tiny+Elvis · · Score: 2, Insightful

    What problems of Lisp (Common Lisp?) macros are you talking about?

  54. Re:Are templates always necessary? by jaoswald · · Score: 2, Insightful

    Look, if you are dealing with a team that has not divided responsibility for design decisions according to a clear system, then that is your real problem, not the lack of compile-time diagnostics. You're also going to get huge numbers of bugs that the compiler *won't* catch.

    The problem with C++ in particular is that it is a bondage-and-discipline language. Everyone on your team has to figure out in advance what chains and barriers are going to be put up in order to allow the problem to be solved within the C++ language.

    In a dynamic language, you *choose* what barriers to put in place in order to maintain safety. You aren't forced to put a lot of barriers up that will never be needed.

    Also, what people miss is that in Lisp, for instance, a run-time error usually puts you in an interactive debug environment, allowing you to make changes to the program (still alive) using the full power of the Lisp language, and the full resources of your program, in order to find the problem, fix it, and continue execution. This is just now coming to pass in the C++ world, with incremental compilation, etc., but Lisp programmers have had this for decades. When you are developing, you will find the errors, and for production, you can write error handlers that catch these various conditions, log them as appropriate, and specify how execution should continue.

    The strategies you use with a dynamic language to prevent and deal with these kinds of problems are different than with static languages like C++. The strategies aren't better or worse, just different. What you gain with dynamic languages is a kind of flexibility that allows you to attack the problem, not the language, and to do so with a maximum payoff for programmer effort. What you gain with C++ is the ability to catch certain types of errors, which aren't really that common, especially as intellisense-type tools are becoming much more widespread. Much of the time, when the compiler complains about type mismatches, you add a cast. The language is forcing you to explain yourself again, not really pointing out a logic error in your program.

    The real problems that programmers face are errors of logic, which no language can address, and the ability to express the desired operation, which dynamic languages make much easier than static languages, because they don't require as much unnecessary or redundant description.