Using Exported TemplatesProblemYou want to build a program that uses exported templates, meaning that it declares templates in headers with the export keyword and places template implementations in .cpp files. SolutionFirst, compile the .cpp files containing the template implementations into object files, passing the compiler the command-line options necessary to enable exported templates. Next, compile and link the .cpp files that use the exported templates, passing the compiler and linker the command-line options necessary to enable exported templates as well as the options to specify the directories that contain the template implementations. The options for enabling exported templates are given in Table 1-39. The options for specifying the location of template implementations are given in Table 1-40. If your toolset does not appear in this table, it likely does not support exported templates. Table 1-39. Options to enable exported templates
Table 1-40. Option to specify the location of template implementations
For example, suppose you want to compile the program displayed in Example 1-27. It consists of three files:
Example 1-27. A simple program using exported templates
plus.hpp:
#ifndef PLUS_HPP_INCLUDED
#define PLUS_HPP_INCLUDED
export template<typename T>
T plus(const T& lhs, const T& rhs);
#endif // #ifndef PLUS_HPP_INCLUDED
plus.cpp:
#include "plus.hpp"
template<typename T>
T plus(const T& lhs, const T& rhs)
{
return rhs + lhs;
}
test.cpp:
#include <iostream>
#include "plus.hpp"
int main( )
{
std::cout << "2 + 2 = " << plus(2, 2) << "\n";
}
To compile plus.cpp to an object file plus.obj using Comeau on Unix, change to the directory containing plus.cpp, plus.cpp, and test.cpp, and enter the following command: $ como -c --export plus.cpp This command also generates a file plus.et describing the template implementations contained in plus.cpp.
Next, compile test.cpp to an object file test.obj, as follows: $ como -c --export test.cpp Finally, link the executable test.exe: $ como --export -o test test.obj The last two commands could also have been combined: $ como --export -o test test.cpp You can now run test.exe: $ ./test 2 + 2 = 4 Alternatively, suppose that the files plus.hpp and plus.cpp are in a directory named plus, while test.cpp is in a sibling directory test. To compile and link test.cpp, change to the directory test and enter: $ como --export --template_directory=../plus -I../plus -o test test.cpp DiscussionC++ supports two models for supplying the definitions of function templates and static data members of class templates: the inclusion model and the separation model. The inclusion model is familiar to all programmers who regularly use C++ templates, but often seems unnatural to programmer accustomed to writing nontemplated code. Under the inclusion model, the definition of a function templateor of a static data member of a class templatemust be included by each source file that uses it. By contrast, for nontemplated functions and data it is sufficient for a source file simply to include a declaration; the definition can be placed in a separate .cpp file. The separation model is closer to the traditional manner of organizing C++ source code. Templates declared with the export keyword do not need to have their definitions included by source files that use them; instead, the definitions can be placed in separate .cpp files. The parallel with traditional source code organization is not exact, though, because even though code that uses an exported template does not need to include its definition, it still depends on the definition in some subtle ways. The separation model offers several potential benefits:
All three potential advantages of the separation model are controversial. First, while some users have reported reduced compile times, the separation model can also lead to longer compile times in some cases. At the moment, there is insufficient data to make a definitive judgment. Second, while the separation model does reduce some forms of symbolic pollution, the language rules necessary to support the separation model, particularly the notion of two-phase lookup , have complicated the way templated code is writteneven when using the inclusion modeland have had some unintended consequences. Third, all existing implementations of the separation model are based on the EDG frontend, and EDG has not yet provided any means to compile source files containing exported template implementations into binary files that can be shipped in lieu of the source. There was an effort in 2003 to remove exported templates from future versions of the C++ standard, but it failed. Consequently, exported templates are a permanent part of the C++ language, and you should learn to use them. |
