Both approaches advocated in the previous sections work well
and conform entirely to the C++ standard. However, this same standard also
provides the alternative mechanism of exporting
templates. This approach is sometimes called the C++ template separation model.
The Keyword export
In principle, it is quite simple to make use of the
export facility: Define the template in just one file, and mark that
definition and all its nondefining declarations with the keyword
export. For the example in the previous section, this results in the
following function template declaration:
Exported templates can be used without their definition being
visible. In other words, the point where a template is being used and the point
where it is defined can be in two different translation units. In our example,
the file myfirst.hpp now contains only the declaration of the member functions of the class
template, and this is sufficient to use those members. Comparing this with the
original code that was triggering linker errors, we had to add only one
export keyword in our code and things now work just fine.
Within a preprocessed file (that is, within a translation
unit), it is sufficient to mark the first declaration of a template with
export. Later redeclarations, including definitions, implicitly keep
that attribute. This is why myfirst.cpp does not need to be modified in
our example. The definitions in this file are implicitly exported because they
were so declared in the #included header file. On the other hand, it is
perfectly acceptable to provide redundant export keywords on template
definitions, and doing so may improve the readability of the code.
The keyword export really applies to function
templates, member functions of class templates, member function templates, and
static data members of class templates. export can also be applied to a
class template declaration. It implies that every one of its exportable members
is exported, but class templates themselves are not actually exported (hence,
their definitions still appear in header files). You can still have implicitly
or explicitly defined inline member functions. However, these inline functions
are not exported:
However, note that the keyword export cannot be
combined with inline and must always precede the keyword
template. The following is invalid:
Limitations of the Separation Model
At this point it is reasonable to wonder why we're still
advocating the inclusion approach when exported templates seem to offer just the
right magic to make things work. There are a few different aspects to this
choice.
First, even four years after the standard came out, only one
company has actually implemented support for the export keyword. Therefore, experience with this feature is not as widespread as other C++
features. Clearly, this also means that at this point experience with exported
templates is fairly limited, and all our observations will ultimately have to be
taken with a grain of salt. It is possible that some of our misgivings will be
addressed in the future (and we show how to prepare for that eventuality).
As far as we know, Edison Design Group, Inc. (EDG) is still that company. Their technology is available through other vendors, however.
Second, although export may seem quasi-magical, it is
not actually magical. Ultimately, the
instantiation process has to deal with both the place where a template is
instantiated and the place where its definition appears. Hence, although these
two seem neatly decoupled in the source code, there is an invisible coupling
that the system establishes behind the scenes. This may mean, for example, that
if the file containing the definition changes, both that file and all the files
that instantiate the templates in that file may need to be recompiled. This is
not substantially different from the inclusion approach, but it is no longer
obviously visible in the source code. As a consequence, dependency management
tools (such as the popular make and nmake programs) that use
traditional source-based techniques no longer work. It also means that quite a
few bits of extra processing by the compiler are needed to keep all the
bookkeeping straight; and in the end, the build times may not be better than
those of the inclusion approach.
Finally, exported templates may lead to surprising semantic
consequences. A common misconception is that the export mechanism
offers the potential of being able to ship libraries of templates without
revealing the source code for their definitions (just like libraries of
nontemplate entities). This is a misconception in the sense that
hiding code is not a language issue: It would be equally possible to provide a
mechanism to hide included template definitions as to hide exported template
definitions. Although this may be feasible (the current implementations do not
support this model), it unfortunately creates new challenges in dealing with
template compilation errors that need to refer to the hidden source code.
Not everybody considers this closed-source approach a plus.
Preparing for the Separation Model
One workable idea is to prepare our sources in such a way that
we can easily switch between the inclusion and export models using a harmless
dose of preprocessor directives. Here is how it can be done for our simple
example:
By defining or omitting the preprocessor symbol
USE_EXPORT, we can now select between the two models. If a program
defines USE_EXPORT before it includes myfirst.hpp, the
separation model is used:
If a program does not define USE_EXPORT, the inclusion
model is used because in this case myfirst.hpp automatically includes
the definitions in myfirst.cpp:
Despite this flexibility, we should reiterate that besides the
obvious logistical differences, there can be subtle semantic differences between
the two models.
Note that we can also explicitly instantiate exported
templates. In this case the template definition can be in another file. To be
able to choose between the inclusion model, the separation model, and explicit
instantion,
-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------
- Complete Tutorial of C++ Template's
- Standard Template Library Tutorial
- Inter Process Communication Tutorial
- Advance Programming in C & C++
-----------------------------------------------------------------
No comments:
Post a Comment