Using Exported Templates

Problem

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

Solution

First, 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

Toolset

Script

Comeau (Unix)

export, -A or strict

Comeau (Windows)

export or A

Intel (Linux)

-export or -strict-ansi[22]

[22] Versions of the Intel compiler for Linux prior to 9.0 used the option -strict_ansi.

Table 1-40. Option to specify the location of template implementations

Toolset

Script

Comeau

template_directory=

Intel (Linux)

-export_dir

For example, suppose you want to compile the program displayed in Example 1-27. It consists of three files:

  • The file plus.hpp contains the declaration of an exported function template plus( ).
  • The file plus.cpp contains the definition of plus( ).
  • The file test.cpp includes the declarationbut not the definitionof plus( ), and defines a main( ) function that uses plus( ).

Example 1-27. A simple program using exported templates

plus.hpp:

#ifndef PLUS_HPP_INCLUDED
#define PLUS_HPP_INCLUDED

export template
T plus(const T& lhs, const T& rhs);

#endif // #ifndef PLUS_HPP_INCLUDED

plus.cpp:

#include "plus.hpp"

template
T plus(const T& lhs, const T& rhs)
{
 return rhs + lhs;
}

test.cpp:

#include 
#include "plus.hpp"

int main( )
{
 std::cout << "2 + 2 = " << plus(2, 2) << "
";
}

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.

For fun, open the file plus.et in a text editor.

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

 

Discussion

C++ 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:

 

Reduced compilation times

Compilation time may improve with the separation model because a template's definition needs to be scanned less frequently and because the separation modules reduce dependencies between modules.

 

Reduced symbolic "pollution"

Names of functions, classes, and data used in a template's implementation file can be completely hidden from code that uses the template, reducing the possibility of accidental name clashes. In addition, the author of a template implementation can worry less about accidental clashes with names from the source files that use the template.

 

The ability to ship precompiled template implementations

In theory, under the separation mode, a vendor could ship template implementations that have been precompiled into a binary format somewhere between C++ source code and ordinary object files.

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.

See Also

Recipe 1.25

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net