|
|
1.1 root 1: Microsoft Foundation Classes Microsoft Corporation
2: Technical Notes
3:
4: #4 : Template Classes and MFC
5:
6: This note describes MFC template class issues and the MFC "templdef"
7: template expansion sample code.
8: =============================================================================
9: The Problem
10: ===========
11:
12: There has long been recognized within the C++ community the need for
13: template classes -- classes that can be instantiated based on an
14: exact type specified by the user. A common example would be a linked
15: list class -- a linked list of what type of object? With template
16: classes the user of the class can specify that: "I want a linked
17: list of CFoo objects."
18:
19: -----------------------------------------------------------------------------
20: The templdef sample
21: ===================
22:
23: While a syntax for template classes has been generally agreed-upon
24: within the C++ community, exact details have not been worked out.
25: We found it useful to provide template classes to the user in the
26: interim. The approach decided upon was to use a syntax for our
27: template classes based on that generally used within the C++
28: community. This syntax is then expanded and modified slightly by a
29: simple template expander called "templdef." For this expansion the
30: user specifies a "typedef'ed" name to be used as an alternative to
31: the template_class<type_specifier> class name.
32:
33: With this approach the Foundation user can begin to write template
34: classes following the generally agreed-upon syntax for C++
35: templates. This code can be ported to the eventual final agreed-upon
36: syntax when the ANSI C++ report is issued. Also, the Foundation user
37: can read the Foundation template classes as general examples of how
38: one writes templates. And the templdef source code provides an
39: example of how one can use the Foundation classes.
40:
41: In order to provide easily readable output from the templdef template
42: expander, we have chosen to leave comments in the expanded output,
43: and to substitute-in textually the type parameters the user
44: specifies. If the user desires to expand template classes over
45: complicated types, use of typedef'ed type names is suggested for
46: template parameters.
47:
48: We advise users wanting to experiment with template classes and
49: templdef should first write and completely debug a non-template
50: version of their class. For example, first write a
51: linked-list-of-CFoos class. When you have that working, then
52: generalize your linked-list-of-CFoos class to a
53: linked-list-of-whatever template class. By taking this approach, you
54: introduce the complicating factor of "template <class CXyz>" syntax
55: *after* you have an already working linked-list class. Finally, you
56: should expect some small changes between the template classes you
57: write today, and the final syntax agreed upon by the ANSI-C++
58: committee.
59:
60: A good way to get started is by examining the .ctt template classes
61: provided with Foundation (found in mfc\sample\templdef subdirectory).
62: The mkcoll.bat file gives examples of the command line syntax of the
63: templdef tool. The general form of the command line syntax is
64: modeled after a C++ typedef of the equivalent template class. As a
65: hypothetical exammple:
66:
67: typedef CArray<CString> CStringArray;
68:
69: becomes:
70:
71: templdef "CArray<CString> CStringArray" array.ctt strarray.h strarray.cpp
72:
73: Note: The actual Foundation template classes are slightly more complicated
74: than this example, taking a number of boolean constant template
75: parameters which allow several slightly different flavors of arrays
76: to be expanded.
77:
78: -----------------------------------------------------------------------------
79: Template source formatting
80: ==========================
81:
82: A source file containing a templdef template class is divided into
83: three sections.
84:
85: The first section consists of comments, usage instructions, copyright
86: notices and the like. This first section is stripped by templdef and
87: is not emitted. The second section starts with a special:
88:
89: //$DECLARE_TEMPLATE
90:
91: directive, after which the template class declaration appears.
92: templdef processes this section to result in the output .h file.
93: After the declaration section comes a special:
94:
95: //$IMPLEMENT_TEMPLATE
96:
97: directive followed by any member function definitions required by the
98: template class. This final section is processed into the resulting
99: .cpp output file.
100:
101: Friend functions, static member definitions, and the like can be
102: included as needed in these sections. Other than #if/#else/#endif
103: sections expanded on a template parameter (see next section),
104: preprocessor commands are left unexpanded in the output files. This
105: permits additional processing by the native compiler preprocessor.
106:
107: One restriction of the templdef implementation is that the first
108: occurance of a template declaration (typically *the* template class
109: declaration) defines *all* name-wise correspondences between template
110: formal parameters and actual parameters throughout the template class
111: file. Thus template parameter names must be used consistently
112: throughout all template declarations and definitions in the template
113: class file. This approach is consistent with the fact that you are
114: expanding on only one particular, out of n possible, template
115: possibilities.
116:
117: -----------------------------------------------------------------------------
118: Template parameters and special #if/#else/#endif processing
119: ===========================================================
120:
121: Templdef template parameters can either be types, or can be
122: compile-time constant expressions. In particular, if a template
123: parameter is "0" or "1", then templdef will evaluate (only)
124: #if/#else/#endif statements based on that constant parameter, and
125: emit only those lines of code corresponding to the true condition.
126: Again, see mkcoll.bat and the Foundation template classes for
127: examples of how to use this feature.
128:
129: The #if/#else/#endif expansion depends on having exactly the manifest
130: constant "1" or "0" as a template parameter. For example, if you
131: were to say "TRUE" or "FALSE" instead, then templdef would leave in
132: the #if/#else/#endif expressions for the preprocessing phase of the
133: compiler to expand later. Also, this templdef evaluation does not
134: take into account nested #if/#else statements -- either make sure
135: your expansion corresponds to an inner-most nesting and use "0" or
136: "1" as your boolean constant template parameter, or say "FALSE" or
137: "TRUE" and let the compiler's preprocessing phase do the
138: #if/#else/#endif expansion later. Another limitation on templdef's
139: capabilities in this area is that it expects #if/#else/#endif
140: statements to be written following the common convention of no
141: intervening space after the '#' sign. If you need to write # .... if
142: / # .... else / # .... endif then let the compiler's preprocessor
143: handle the job instead.
144:
145: -----------------------------------------------------------------------------
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.