|
|
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.