FAQ: A template describes how to build definitions (classes or functions) which are basically the same.

One application is type-safe containers; there are many, many more.

FQA: Let's get a bit more specific. The FAQ's answer is applicable to C macros, Lisp macros, ML functors, functions like eval found in many interpreted languages, OS code that generates assembly instructions used to handle interrupts at run time, and just plain code generation (writing programs that print source code). The purpose of all such devices is meta-programming - writing code that works with code, creating pieces of code which are "basically the same" (after all, they are built from the same rules), and yet have some interesting differences. The question is, how do we specify these rules and these differences?

The approach used in C++ templates is to use integral constants and types to represent the differences, and to use class & function definitions to represent the rules. The first decision prevents you from generating code dynamically, because the parameters can only be compile-time entities. The second decision prevents almost everything else, because you don't get to use a programming language to generate code - the only thing you can do is write code with some things factored out and made parameters. You can't do as simple and useful a set of "basically the same" classes as automatically generated class wrappers for remote procedure calls instead of normal "local" function calls (called "proxies and stubs" in COM terminology; there are many other terms). Even computing the factorial of an integer parameter is done using so much code abusing the language mechanisms that people with no useful work to do are proud of being able to accomplish this.

Beyond those fundamental limitations, templates follow the tradition of C++ features of interacting poorly with each other. Templates can't be compiled because they are not code - they are, well, templates from which code can be generated once you have the parameters, and then you can compile it. C++, like C, defines no way to locate the compiled code of a definition given its name. Consequently, template definitions are placed in #include files, and recompiled in each translation unit each time they are instantiated, even if the exact same instantiation is used in N other files. This problem is amplified by the tremendous complexity of the C++ grammar (the most complicated part of it is probably templates themselves), making this recompilation very slow. If your code doesn't compile, you get cryptic error messages. If it does compile, you might wonder what it means. That's where the interactions of the C++ type system (pointers, arrays, references, constants, literals...), function & operator overload resolution, function & class template specialization selection, built-in and user-defined implicit conversions, argument-dependent name look-up, namespaces, inheritance, dynamic binding and other things kick in. The sheer length of this list should be convincing: neither a human nor a program (say, an IDE) has a chance against this unprecedented syntactic power.

Poor support for meta-programming is not necessarily a very big deal, because you can do lots and lots of things without it. That is, unless you work in C++. For example, there are no built-in lists or dictionaries in C++; the standard library provides templates you can use, so you can recompile the definition of each kind of dictionary each time you use it in a source file. In fact, most of the code in the C++ standard library belongs to a conceptually and historically separate library called STL, which stands for "Standard Template Library". For example, that's where std::vector, which the FAQ recommends to use instead of the evil C arrays, comes from.

If you use C++, chances are that you're going to deal a lot with its obscure meta-programming facilities
Designed By Blogger Templates | Templatelib & Distributed By Blogspot Templates