However, the application of ideals must be tempered by practical constraints, and separate compilation of templates is expensive on some implementations.
Whichever strategy is used, non- i
in
nl
li
in
ne
e s
st
ta
at
ti
ic
c members (§C.13.1) must have a unique definition
in some compilation unit. This implies that such members are best not used for templates that are otherwise included in many translation units.
One ideal is for code to work the same whether it is compiled as a single unit or separated into several separately translated units. That ideal should be approached by restricting a template definition’s dependency on its environment rather than by trying to carry as much as possible of its definition context with it into the instantiation process.
13.8 Advice [temp.advice]
[1] Use templates to express algorithms that apply to many argument types; §13.3.
[2] Use templates to express containers; §13.2.
[3] Provide specializations for containers of pointers to minimize code size; §13.5.
[4] Always declare the general form of a template before specializations; §13.5.
[5] Declare a specialization before its use; §13.5.
[6] Minimize a template definition’s dependence on its instantiation contexts; §13.2.5, §C.13.8.
[7] Define every specialization you declare; §13.5.
[8] Consider if a template needs specializations for C-style strings and arrays; §13.5.2.
[9] Parameterize with a policy object; §13.4.
[10] Use specialization and overloading to provide a single interface to implementations of the same concept for different types; §13.5.
[11] Provide a simple interface for simple cases and use overloading and default arguments to express less common cases; §13.5, §13.4.
[12] Debug concrete examples before generalizing to a template; §13.2.1.
[13] Remember to e
ex
xp
po
or
rt
t template definitions that need to be accessible from other translation units; §13.7.
[14] Separately compile large templates and templates with nontrivial context dependencies; §13.7.
[15] Use templates to express conversions but define those conversions very carefully; §13.6.3.1.
[16] Where necessary, constrain template arguments using a c
co
on
ns
st
tr
ra
ai
in
nt
t() member function;
§13.9[16].
The C++ Programming Language, Third Edition by Bjarne Stroustrup. Copyright ©1997 by AT&T.
Published by Addison Wesley Longman, Inc. ISBN 0-201-88954-4. All rights reserved.
Section 13.8
Advice 353
[17] Use explicit instantiation to minimize compile time and link time; §C.13.10.
[18] Prefer a template over derived classes when run-time efficiency is at a premium; §13.6.1.
[19] Prefer derived classes over a template if adding new variants without recompilation is important; §13.6.1.
[20] Prefer a template over derived classes when no common base can be defined; §13.6.1.
[21] Prefer a template over derived classes when built-in types and structures with compatibility constraints are important; §13.6.1.
13.9 Exercises [temp.exercises]
1. (∗2) Fix the errors in the definition of L
Li
is
st
t from §13.2.5 and write out C++ code equivalent to
what the compiler must generate for the definition of L
Li
is
st
t and the function f
f(). Run a small
test case using your hand-generated code and the code generated by the compiler from the template version. If possible on your system given your knowledge, compare the generated code.
2. (∗3) Write a singly-linked list class template that accepts elements of any type derived from a class L
Li
in
nk
k that holds the information necessary to link elements. This is called an intrusive list.
Using this list, write a singly-linked list that accepts elements of any type (a non-intrusive list).
Compare the performance of the two list classes and discuss the tradeoffs between them.
3. (∗2.5) Write intrusive and non-intrusive doubly-linked lists. What operations should be provided in addition to the ones you found necessary to supply for a singly-linked list?
4. (∗2) Complete the S
St
tr
ri
in
ng
g template from §13.2 based on the S
St
tr
ri
in
ng
g class from §11.12.