TITLE: an opinion on the utility of templates (Newsgroups: comp.lang.c++,comp.lang.c++.moderated, 9 Mar 98) SKETTLE: skettle@algorithmics.com (Steve Kettle) > Hello there I'm trying to get a list of the advantages of using templates > in C++. Templates look quite appealing at first, however do they really > add enough functionality to justify the added complexity to the language. KANZE: jkanze@otelo.ibmmail.com Yes. I actually don't like templates either, but the alternatives still seem worse. I don't define templates in application code, but I do use template classes like vector, map or list, and have almost since I started using C++. Of course, when I started using C++, it was called generic.h, rather than templates. For the use I make of them, templates don't offer much over generic.h FOR THE USER. Having developped containers like map and vector with generic.h, however, I can assure you that templates are an enormous win for the person who has to maintain these classes, and they do offer some small advantages for the user, particularly in large projects. SKETTLE: > Java has no templates. If you think that templates are a necessary > feature then can you give an example of code using templates in C++ that > would be quite a bit more complicated to implement in Java? KANZE: Just about any type-safe container. Or how about a container that can be instantiated with either user defined types OR basic types. (In Java, the solution is to have a container of Object. But basic types don't convert to and from Object, so you need to use Integer, etc., rather than int.) SKETTLE: > I realize that templates allow run time performance but I am not convinced > that they added anything else to the language but unecessary complexity. KANZE: The run-time improvement is negligible in many cases. The real advantage, as opposed to the way it is done in Java, is the compile time type checked rather than the run-time type checking. As I see it, there are only three alternatives: 1. Macro expansion, a la generic.h. Try developing a complicated container (map, AVL tree, etc.) with this, and then we'll talk about it. Technically, a real pain for the container developer. The fact that you have to explicitly instantiate the implementation in exactly one place is also a nuisance for the user of the container, although this can generally be automated with the makefile and some shell scripts. 2. Use a common base class, e.g.: Object, as in Java. This is fine for languages like Lisp or SmallTalk, which only do dynamic type checking, but putting off until run-time what you can do at compile time is not consistent with the philosophy of C++ (performance cost) nor Java (rigorous type checking for safety reasons). My own experience (not conclusive) is that while strictly dynamic type checking is fine for smaller prototpyes, for large projects, the more the compiler can check, the more it helps. 3. Some sort of generic mechanism, like templates. IMHO, this is the best solution, when it works. The problem it poses is one of instantiation context. Explicit declaration of use, and/or strict modules, help here: Modula-3 doesn't have any problems, and I've not heard of this as the source of Ada's complexity. Regretfully, Java's packages are open, more like C++ namespace than Ada's package (I think) or Modula-3's modules. Formally, the C++ template model is very dangerous. I would have no problem showing you 100's of ways it can introduce subtle errors. I don't like it because of this, because it means I'm never 100% sure my programs are correct. BUT... in practice, the errors are rare. Even if I'm not always able to show that they aren't present, their effective cost is very low. Much lower than the cost of the alternatives to templates. (At least the three cited above. Does anyone know of any others?) SKETTLE: > Stroustroup believes that Java will eventually need some type of template > mechanism but he doesn't explain why. KANZE: I agree with Stroustrup here. The why is easy: Java is (like C++) a statically typed language. It even makes a big deal of its features supporting "provability". Requiring a container to hold Object's, and downcasting on extraction (which is the current Java idiom) flies in the face of this. If Java doesn't have templates today, it is certainly because they are afraid of the complexity of the C++ model. But unless they can find a safe alternative, they will have to offer some form of generic classes, sooner or later. (It's interesting to note that some early Java documents apparently listed "generic" as a keyword reserved for future expansion.) Note that the complexity in C++ templates comes from several sources. One source is that C++ attempts to allow templates to be used as a true meta-language, supporting things like template expressions, etc. This is fine for experimental purposes, but I don't think that Java will ever deem support for it as essential, or worth the effort. Another source is the automatic type induction for template functions. I would consider this an agreeable feature, but hardly essential, at least for the essential uses of templates. (It may be essential in the more extreme idioms of template usage, or in template expressions.) Finally, however, IMHO, the largest part of the complexity is in specifying the context of instantiation. And I don't see how Java can avoid this one. SKETTLE: > It's not obvious to me why > templates are necessary, except maybe for a run-time performance. At first > glance the functionality that templates add can be duplicated with virtual > functions. KANZE: Yes and no. You also need dynamic_cast, for objects extracted from a container. (This is not to say that much of what people are doing currently with templates shouldn't be done with virtual functions.) But the important gain that templates bring is compile time type checking, and thus, added safety. Which sounds like an argument relative to Java as well. (I would probably be unfair if I didn't mention that the number of errors due to incorrect downcasts when extracting an object from an untyped container is not enormous either. But--at least for me--the final cost analysis still favors templates.)