Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 1 of 18
Go Back
Full Screen
Quit
Introduction to C++ Templates
and Template Instantiation
Brian A. MalloySchool of Computing
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 2 of 18
Go Back
Full Screen
Quit
The Inscrutible Alexandrescu
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 3 of 18
Go Back
Full Screen
Quit
1. Why Templates
• Code clones are a maintenance problem:
int temp = x; float temp = x;
x = y; x = y;
y = temp; y = temp;
• If language doesn’t support a code reusefeature for different types:
1. void*
2. macros & preprocessor
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 4 of 18
Go Back
Full Screen
Quit
1.1. Macros
#include <iostream>
#define MAX(a,b) (((a)>(b))?(a):(b))
int main() {
std::cout << MAX(5, 3) << std::endl;
std::cout << MAX(2.5, 5.2) << std::endl;
}
• Macros are error prone⇒ no type checking
• macros can be hard to read
• Templates are functions or classes for morethan one type.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 5 of 18
Go Back
Full Screen
Quit
1.2. A generic function
template <typename T>
const T& larger(const T a, const T b) {
return a > b ? a : b;
}
int main() {
std::cout << ::larger(3, 7) << std::endl;
std::cout << ::larger(3.5, 7.1) << std::endl;
return 0;
}
larger ⇒ a family of functions that return thelarger of two values, passed as parameters: a, b.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 6 of 18
Go Back
Full Screen
Quit
1.3. The keyword typename
• Introduces a type parameter
• Parameters can also be ordinary values orconstants.
• Historically, the keyword class was usedto define a type parameter. Semanticallythere’s no difference between using class andtypename; however, since types other thanclasses are permitted in function larger, weuse typename to avoid confusion.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 7 of 18
Go Back
Full Screen
Quit
1.4. typename is sometimes needed to dis-tinguish expression from declaration
template <typename T>
inline void printElements(const T &coll) {
typename T::const_iterator pos;
for (pos = coll.begin();
pos != coll.end(); ++pos) {
std::cout << *pos << ’ ’;
}
std::cout << std::endl;
}
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 8 of 18
Go Back
Full Screen
Quit
1.5. A (canonical) generic class
1 #include <vector>
2 template <typename TYPE>
3 class Stack {
4 public:
5 Stack() : _top(EMPTY) {}
6 TYPE top();
7 void pop();
8 void push(TYPE x);
10 private:
11 int _top;
13 enum { EMPTY = -1 };
14 std::vector<TYPE> items;
15 };
******************************************
Line #13 ⇒ the enum hack.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 9 of 18
Go Back
Full Screen
Quit
2. Using Templates
• A function or class template is not a func-tion or a class until it’s instantiated.
• Moreover, each template function or classs/b instantiated only once for each type.
• linker must avoid dupe of same template
• Two models for incorporating templates:
1. Inclusion Model
2. Explicit Instantiation Model
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 10 of 18
Go Back
Full Screen
Quit
2.1. C++ Separate Compilation
1. Assume stack is ordinary class ⇒ no tem-plates
2. stack code appears once, and two objectsare instantiated: for a, and for b.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 11 of 18
Go Back
Full Screen
Quit
2.2. Instantiating a template stack
1. Now the compiler has to build a class: stackof ints using the template specification.
2. But we only want one stack of ints
3. Use explicit instantiation to make onestack of ints (.h and .cpp in separate files)
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 12 of 18
Go Back
Full Screen
Quit
3. The Inclusion Model
Put declaration and definition in one file:
1 #include <iostream>
2
4 const T& larger(const T& a, const T& b) {
5 return a > b ? a : b;
6 }
7
8 int main() {
9 std::cout << larger(6, 8) << std::endl;
10 std::cout << larger(2.5, 99.3) << std::endl;
11 }
Two functions, larger, will be built: one for in-tegers and one for double.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 13 of 18
Go Back
Full Screen
Quit
3.1. If we separate the declaration anddefinition, we get link errors
************** larger.h **************
template <typename T>
const T& larger(const T& a, const T& b);
************** larger.cpp **************
#include "larger.h"
template <typename T>
const T& larger(const T& a, const T& b) {
return a > b ? a : b;
}
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 14 of 18
Go Back
Full Screen
Quit
*************** main.cpp ***************
#include "larger.h"
int main() {
std::cout << larger(6, 8) << std::endl;
}
undefined reference to:‘int const& larger<int>(int, int)’
• This error message means ⇒ the compilerdidn’t build a function larger for ints!
• To build one, must explicitly tell the com-piler to do it,
• and then “he” will come!
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 15 of 18
Go Back
Full Screen
Quit
4. Explicit Instantiation Model#include <iostream>
#include "larger.h"
int main() {
std::cout << larger(6, 8) << std::endl;
std::cout << larger(9.1, 2.5) << std::endl;
}
********************************************
Instantiate for each type used:
template int
const& larger<int>(int, int);
template double
const& larger<double>(double, double);
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 16 of 18
Go Back
Full Screen
Quit
int main() {
Stack<int> intStk;
Stack<char> charStk;
}
***********************************
Instantiate for each type used:
template class Stack<int>;
template class Stack<char>;
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 17 of 18
Go Back
Full Screen
Quit
4.1. Tradeoffs of Inclusion Model
• Disadvantage: increased compilation timesfor large programs.
• Advantage: guaranteed to have instancesfor any type.
• The inclusion model is favored over othermodels, even though build time increases.
Why Templates
Using Templates
The Inclusion Model
Explicit . . .
JJ II
J I
Slide 18 of 18
Go Back
Full Screen
Quit
4.2. Tradeoffs for Explicit Instantiation
• Disadvantage of manual instantiation: youmay instantiate for types on one system,but may be different on another system.
• Advantages of explicit instantiation:
– The overhead of large headers is avoided.
– Source code for template definitions ishidden
– For some applications, it may be ad-vantageous to control the location ofinstantiation.