Templates
Document Sample


Templates
Kenneth Chiu
More Unsigned Questions
• What does this print?
– size_t a = 3, b = 5;
size_t u = 10;
long long ll = 10;
u += a - b;
ll += a - b;
printf("%u, %lld\n",
(unsigned int) u, ll);
Pointers to Members
• “All problems in computer science can be
solved with another level of indirection”
– Butler Lampson
– class A {
int f(int); int g(int); };
A a;
foo(&a, ?);
• Pointers to members
– void foo(A *a, int (A::*fp)(int));
foo(&a, &A::f);
• #include <stdio.h>
class A {
public:
int f(int) { printf("Called A::f().\n"); }
int g(int) { printf("Called A::g().\n"); }
};
void f(A *a, int (A::*ptm)(int)) {
(a->*ptm)(0);
}
int main() {
A a;
f(&a, &A::g);
f(&a, &A::f);
}
Introduction
• A template is just that, a template or “pattern”.
• Essentially a macro on steroids.
• How is a template different from normal source
code?
– void foo() {…}
template <typename T>
void foo1() {…}
– Template definitions are not really “compiled”.
• Just cause things to be remembered.
• Some of these slides might be hard to
understand, so please interrupt if I go to fast.
Templates Are Macros
• Where do you put templates, header files
or implementation files?
– Every use must be preceded in the same
translation unit by its definition.
– Private template could be in an
implementation file.
Templates and Classes as Models
• Both are “models”.
– Classes are models for objects. An object:
• Has source code (member functions).
• Has data (member variables).
• But source code never differs.
• Data layout never differs. Only the values differ.
– Templates go back one step. They are models for
classes. You first instantiate a template to fix a
particular source code and data layout.
• The source code can differ.
• The data layout can differ.
How Do Templates Get Instantiated?
• Implicitly
– template <typename T>
void foo(T) {…}
foo(1);
– What happens if later on in this translation unit you have:
• foo(4);
• foo(3.14);
– What happens if later on in a different translation unit you have:
• foo(5);
• What really happens?
• Explicitly
– template void foo<int>(int);
– What happens if later on in this translation unit you have:
• template void foo<int>(int);
• foo(4);
How Do Templates Get Instantiated?
• What happens if a template is implicitly
instantiated in one translation unit, and explicitly
in another?
• What if it is first implicitly instantiated, then
explicitly instantiated in the same translation
unit?
• Trying to remember all the rules will drive you
crazy.
– Instead understand the purpose of instantiation, and
understand the underlying techniques.
– This will help you immensely when trying to track
down errors.
Function Templates
• Defining min():
– #define min(a, b) ((a) < (b)) ? (a) : (b))
– Any problems with this?
• Basic syntax
– template <typename T>
T min(T a, T b) { return a < b ? a : b; }
– What changes would you make to the above?
• What happens when called with ++?
• g++ standard library definition
– template<typename _Tp>
inline const _Tp&
min(const _Tp& __a, const _Tp& __b) {
if (__b < __a) return __b; return __a; }
– Why the underscores?
Non-Type Parameters
• Why might this be useful?
– template <typename T, int N>
void sort(T (&a)[N]) {
T save[N];
if (i < N) {…}
}
Specialization
• Consider:
– template <typename T>
T min(T a, T b) {
return (a < b) ? a : b; }
• What happens when you call?
– min(“a”, “b”)
• Define
– template <>
const char *
min(const char *a, const char *b) {
return (strcmp(a, b) < 0) ? a : b; }
Typenames
• Consider
– template <typename T>
void foo(T) {
T::name * p; }
• What is T::name?
• Use typename keyword
– template <typename T>
void foo(T) {
typename T::name * p; }
Template Mixed with Nontemplate
• Is this valid?
– template <typename T>
T sum(T, int);
double sum(double, double);
• Which one gets called?
– sum(3.14, 3.14);
– sum(3.14, 1);
– sum(1, 3.14);
• Know what you don’t know.
– Known unknowns are okay, unknown unknowns are
bad. (Especially if your initials are D.R.)
Template Argument Deduction
• Consider
– template <typename T>
T min(T a, T b) {
return a < b ? a : b; }
• What happens when you call?
– min(1, 3.14)
• Explicit arguments
– min<double>(1, 3.14)
Class Templates
• Consider
– template <typename T, int N>
class Array {
T a[N];
T operator[](int i) {
return a[i]; }
};
• How do you use this?
– Array<int, 10> a;
• How might you improve this?
– Range check, Lvalue, const
Specializations
• Specialize member functions individually:
– template <>
double A<double>::foo() {…}
• Where do these go, header or program
text?
– Must place a declaration before point of
instantiation.
• Specialize whole class template
– template <typename T> class A {…};
template <> class A<double> {…};
• Where do these go?
• Traits
– template <> class Traits<Alice> {
static const Color
hair_color = BLACK;
static const Color
eye_color = BLACK;
static const int
weight = 135;
};
template <> class Traits<Bob> {…};
color = Traits<Bob>::hair_color;
Partial Specialization
• template <typename T1, int N>
class A {…};
template <typename T1>
class A<T1, 2> {…};
• template <typename T1, int N>
class A< T1, N < 2 > {…};
Member Templates
• A member function can be a template:
– class A {
template <typename T>
T foo(T);
};
– For example, suppose you are writing an XML
serializer:
• class Serializer {
template <typename T>
void emit(T v) const {
sprintf(p, ???, v);
Related docs
Get documents about "