home *** CD-ROM | disk | FTP | other *** search
- Microsoft Foundation Classes Microsoft Corporation
- Technical Notes
-
- #4 : Template Classes and MFC
-
- This note describes MFC template class issues and the MFC "templdef"
- template expansion sample code.
- =============================================================================
- The Problem
- ===========
-
- There has long been recognized within the C++ community the need for
- template classes -- classes that can be instantiated based on an
- exact type specified by the user. A common example would be a linked
- list class -- a linked list of what type of object? With template
- classes the user of the class can specify that: "I want a linked
- list of CFoo objects."
-
- -----------------------------------------------------------------------------
- The templdef sample
- ===================
-
- While a syntax for template classes has been generally agreed-upon
- within the C++ community, exact details have not been worked out.
- We found it useful to provide template classes to the user in the
- interim. The approach decided upon was to use a syntax for our
- template classes based on that generally used within the C++
- community. This syntax is then expanded and modified slightly by a
- simple template expander called "templdef." For this expansion the
- user specifies a "typedef'ed" name to be used as an alternative to
- the template_class<type_specifier> class name.
-
- With this approach the Foundation user can begin to write template
- classes following the generally agreed-upon syntax for C++
- templates. This code can be ported to the eventual final agreed-upon
- syntax when the ANSI C++ report is issued. Also, the Foundation user
- can read the Foundation template classes as general examples of how
- one writes templates. And the templdef source code provides an
- example of how one can use the Foundation classes.
-
- In order to provide easily readable output from the templdef template
- expander, we have chosen to leave comments in the expanded output,
- and to substitute-in textually the type parameters the user
- specifies. If the user desires to expand template classes over
- complicated types, use of typedef'ed type names is suggested for
- template parameters.
-
- We advise users wanting to experiment with template classes and
- templdef should first write and completely debug a non-template
- version of their class. For example, first write a
- linked-list-of-CFoos class. When you have that working, then
- generalize your linked-list-of-CFoos class to a
- linked-list-of-whatever template class. By taking this approach, you
- introduce the complicating factor of "template <class CXyz>" syntax
- *after* you have an already working linked-list class. Finally, you
- should expect some small changes between the template classes you
- write today, and the final syntax agreed upon by the ANSI-C++
- committee.
-
- A good way to get started is by examining the .ctt template classes
- provided with Foundation (found in mfc\sample\templdef subdirectory).
- The mkcoll.bat file gives examples of the command line syntax of the
- templdef tool. The general form of the command line syntax is
- modeled after a C++ typedef of the equivalent template class. As a
- hypothetical exammple:
-
- typedef CArray<CString> CStringArray;
-
- becomes:
-
- templdef "CArray<CString> CStringArray" array.ctt strarray.h strarray.cpp
-
- Note: The actual Foundation template classes are slightly more complicated
- than this example, taking a number of boolean constant template
- parameters which allow several slightly different flavors of arrays
- to be expanded.
-
- -----------------------------------------------------------------------------
- Template source formatting
- ==========================
-
- A source file containing a templdef template class is divided into
- three sections.
-
- The first section consists of comments, usage instructions, copyright
- notices and the like. This first section is stripped by templdef and
- is not emitted. The second section starts with a special:
-
- //$DECLARE_TEMPLATE
-
- directive, after which the template class declaration appears.
- templdef processes this section to result in the output .h file.
- After the declaration section comes a special:
-
- //$IMPLEMENT_TEMPLATE
-
- directive followed by any member function definitions required by the
- template class. This final section is processed into the resulting
- .cpp output file.
-
- Friend functions, static member definitions, and the like can be
- included as needed in these sections. Other than #if/#else/#endif
- sections expanded on a template parameter (see next section),
- preprocessor commands are left unexpanded in the output files. This
- permits additional processing by the native compiler preprocessor.
-
- One restriction of the templdef implementation is that the first
- occurance of a template declaration (typically *the* template class
- declaration) defines *all* name-wise correspondences between template
- formal parameters and actual parameters throughout the template class
- file. Thus template parameter names must be used consistently
- throughout all template declarations and definitions in the template
- class file. This approach is consistent with the fact that you are
- expanding on only one particular, out of n possible, template
- possibilities.
-
- -----------------------------------------------------------------------------
- Template parameters and special #if/#else/#endif processing
- ===========================================================
-
- Templdef template parameters can either be types, or can be
- compile-time constant expressions. In particular, if a template
- parameter is "0" or "1", then templdef will evaluate (only)
- #if/#else/#endif statements based on that constant parameter, and
- emit only those lines of code corresponding to the true condition.
- Again, see mkcoll.bat and the Foundation template classes for
- examples of how to use this feature.
-
- The #if/#else/#endif expansion depends on having exactly the manifest
- constant "1" or "0" as a template parameter. For example, if you
- were to say "TRUE" or "FALSE" instead, then templdef would leave in
- the #if/#else/#endif expressions for the preprocessing phase of the
- compiler to expand later. Also, this templdef evaluation does not
- take into account nested #if/#else statements -- either make sure
- your expansion corresponds to an inner-most nesting and use "0" or
- "1" as your boolean constant template parameter, or say "FALSE" or
- "TRUE" and let the compiler's preprocessing phase do the
- #if/#else/#endif expansion later. Another limitation on templdef's
- capabilities in this area is that it expects #if/#else/#endif
- statements to be written following the common convention of no
- intervening space after the '#' sign. If you need to write # .... if
- / # .... else / # .... endif then let the compiler's preprocessor
- handle the job instead.
-
- -----------------------------------------------------------------------------
-