TEMPLDEF: Tool That Expands C++ Templates

The TEMPLDEF tool is a C++ template expander that has been used to create the simple Microsoft Foundation Class (MFC) collection classes that are not based on C++ templates. The nontemplate collection classes have been provided by MFC beginning with MFC 1.0. MFC now provides collection classes implemented using C++ templates, namely: CList, CArray, CMap, CTypedPtrList, CTypedPtrArray, and CTypedPtrMap. If you write new type-safe collection classes for your own data types, you should use the newer template-based classes.

MFC still includes the simple collection classes such as CByteArray and CStringList. The TEMPLDEF tool expands C++ template-like source files, such as Array.ctt in the TEMPLDEF sample directory, to create CByteArray. A console application such as TEMPLDEF is linked with the same variant of the MFC library as GUI (graphical user interface) applications.

TEMPLDEF uses a syntax similar to the ANSI C++ language syntax. The TEMPLDEF tool expands a template file into sources for a user-specified class_name, which can then be used as an alternative to:

template_class<type_specifier> class_name

In addition to being a useful tool, the source code provided for TEMPLDEF serves as an example of a console application using the Microsoft Foundation Class Library (MFC).

You can model your template classes after the source files for four collection types provided in the TEMPLDEF sample directory — arrays, lists, maps from keys to values, and maps from strings to values.

To get a quick look at how the TEMPLDEF tool works, build the Templdef.exe and run Mkcoll.bat from the TEMPLDEF sample directory.

Mkcoll.bat reproduces the sources for all of the Foundation collection classes, whose sources and headers are included in the \Microsoft Visual Studio\VC98\MFC\SRC and MFC\Include directories. For example, one of the source files produced by Mkcoll.bat is Array_b.cpp, which is the implementation for the CByteArray class. This file is exactly the same as the Array_b.cpp file in MFC\SRC.

The TEMPLDEF command lines in Mkcoll.bat provide a model for how to run TEMPLDEF to produce additional type-specific collection classes, as explained in the next section. The collection template source files (Array.ctt, List.ctt, Map.ctt, and Map_s.ctt) provide models for how to develop your own template classes.

Producing Additional Type-Specific Collection Classes

The TEMPLDEF sample directory provides sources for four types of collections:

  • Array.ctt is the template for the array collection shape.

  • List.ctt is the template for the list collection shape.

  • Map.ctt is the template for the collection shape that maps keys of a specified type to values of a specified type.

  • Map_s.ctt is the template for the collection shape that maps keys of a specific CString type to values of some specified type.

The command-line syntax for running TEMPLDEF to produce a type-specific collection is illustrated by the following example from Mkcoll.bat:

templdef "CArray<BYTE,BYTE,1,0> CByteArray" array.ctt temp.h temp.inl array_b.cpp
  • "CArray" is the template name, as would be specified in the C++ syntax for the template class.

  • The first template argument, BYTE, is the data type, such as that used for the return type of CByteArray::GetAt.

    BYTE GetAt(int nIndex) const;

  • The second template argument, BYTE, is the data type, when referred to as an argument to a member function of the template class.

    void SetAt(int nIndex, BYTE newElement);

  • The third template argument, 1, sets the value for IS_SERIAL, which determines whether the template class is declared with the DECLARE_SERIAL macro and has a Serialize member function.

  • The fourth template argument, 0, sets the value for HAS_CREATE, which determines whether the template class has additional ConstructElement and DestructElement member functions that are optimized for a particular element type. The library provides such optimization only for the CString type. You should set this argument to 1 only if the element type is CString.

  • "CByteArray" is the name of the expanded template class produced by TEMPLDEF.

  • "Array.ctt" is the source file for the class template.

  • "Temp.h" is the header file produced for the expanded template class.

  • "Temp.inl" is the inline file produced for the template class.

  • "Array_b.cpp" is the implementation file produced for the expanded template class.

Note   Mkcoll.bat concatenates the header and inline files for all of the Foundation collection classes. The resulting Newcoll.h and Newcoll.inl files are the same as the Afxcoll.h and Afxcoll.inl files in MFC\Include. It is neither necessary nor advised to append your own additional collection classes to Afxcoll.h and Afxcoll.inl.

This sample demonstrates the following keywords:

CFile::Open; ConstructElements; CStdioFile::ReadString; CStdioFile::WriteString; CString::GetLength; DestructElements; exit; fprintf; fputc; isalnum; isalpha; isdigit; isspace; strncpy