templates. before we dive in 2 preprocessing compilation linkage
TRANSCRIPT
![Page 1: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/1.jpg)
Templates
![Page 2: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/2.jpg)
Before we dive in
2
• Preprocessing• Compilation• Linkage
![Page 3: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/3.jpg)
Motivation
3
A useful routine to have is
void swap( int& a, int &b ) { int tmp = a; a = b; b = tmp; }
![Page 4: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/4.jpg)
Example
4
What happens if we want to swap a double ? or a string?
For each one, we need different function:
void swap( double& a, double &b ) { double tmp = a; a = b; b = tmp; } void swap( string& a, string &b ) { string tmp = a; a = b; b = tmp; }
![Page 5: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/5.jpg)
Generics Using void*
5
C approach:
void swap( void *a, void *b, size_t size ) { for (size_t i=0; i<size; i++) { char t = *(char *)(a+i); *(char *)(a+i) = *(char*)(b+i); *(char*)(b+i) = t; }
// or can be done using malloc and memcpy}
![Page 6: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/6.jpg)
Generic Programming
6
All these versions of Swap are “isomorphic”:
// code for swap for arbitrary type T void swap( T& a, T &b ) { T tmp = a; a = b; b = tmp; } Can we somehow tell the compiler (not
preprocessor) to use swap with any type T?
![Page 7: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/7.jpg)
Function Templates
7
The template keyword defines “templates”
Piece of code that will be regenerated with different arguments each time
template<typename T> // T is a //"type argument" void swap( T& a, T& b ) { T tmp = a; a = b; b = tmp; }
![Page 8: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/8.jpg)
These two definitions are exactly the same, if we have both, we will have a compilation error:
8
template <typename T>
void swap(T &a, T &b)
{ T c = a; a = b; b = c; }
template <class P> void swap(P &a, P &b) { P c = a; a = b; b = c; }
![Page 9: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/9.jpg)
Template Instantiation
9
int main() { int a = 2; int b = 3; swap( a, b ); // requires swap(int&, int&)
} The compiler encounters swap(T&, T&) It instantiates the template swap with T = intand compiles the code defined by it.
![Page 10: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/10.jpg)
Template Instantiation
10
Different instantiations of a template can be generated by the same program
int a = 2; int b = 3; cout << "Before " << a << " " << b << "\n"; swap( a, b ); // Compiler generates the code for // swap(int&,int&)cout << "After " << a << " " << b << "\n"; double x = 0.1; double y = 1.0; cout << "Before " << x << " " << y << "\n"; swap( x, y ); // Compiler generates the code for // swap(double&,double&)cout << "After " << x << " " << y << "\n";
![Page 11: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/11.jpg)
Template Instantiation
11
Explicit
double d1 = 4.5, d2 = 6.7; swap<double>(d1, d2);
Implicit
double d1 = 4.5, d2 = 6.7; swap(d1, d2);
![Page 12: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/12.jpg)
Template assumptions
12
// example of a uncopyable class class Cookie { private: // private copy operations Cookie(const Cookie&); Cookie & operator=(const Cookie&); public: Cookie() { }; };
... Cookie van, choc; swap(van, choc); /* compiler will try generate code for swap(Cookie&,Cookie&), but will fail, claiming an error somewhere at the declaration of swap*/
Why?
![Page 13: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/13.jpg)
Templates & Compilation
13
• A template is a declaration • The compiler performs functions/operators
calls checks only when a template is instantiated with specific arguments - then the generated code is compiled.
Implications:
1. Template code has to be visible by the code that uses it (i.e., appear in header .h/.hpp file)
2. Compilation errors can occur only in a specific instance
![Page 14: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/14.jpg)
Templates & Compilation
14
• A template is a declaration • The compiler performs functions/operators
calls checks only when a template is instantiated with specific arguments - then the generated code is compiled.
Implications:
1. Template code has to be visible by the code that uses it (i.e., appear in header .h/.hpp file)
2. Compilation errors can occur only in a specific instance
Not just the declaration
![Page 15: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/15.jpg)
Another Example
15
// Inefficient generic sort template< typename T > void sort( T* begin, T* end ) { for( ; begin != end; begin++ ) for( T* q = begin+1; q != end; q++ ) { if( *q < *begin ) swap( *q, *begin ); }}
What are the template
assumptions?
![Page 16: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/16.jpg)
Another Example
16
// Inefficient generic sort template< typename T > void sort( T* begin, T* end ) { for( ; begin != end; begin++ ) for( T* q = begin+1; q != end; q++ ) { if( *q < *begin ) swap( *q, *begin ); }}
What are the template
assumptions?
![Page 17: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/17.jpg)
Usage
17
Suppose we want to avoid writing operator != for new classes
template <typename T> bool operator!= (T const& lhs, T const& rhs) { return !(lhs == rhs);
}
When is this template used?
![Page 18: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/18.jpg)
Usage
18
class MyClass { public: bool operator== (MyClass const & rhs) const; }; int a, b; if( a != b ) // uses built in // operator!=(int,int) ...MyClass x,y; if( x != y ) // uses template with // T= MyClass
![Page 19: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/19.jpg)
When Templates are Used? – overloads, again
19
When the compiler encounters
…
f( a, b )…
1. Look for all functions named f.
2. Creates instances of all templates named f according to parameters.
3. Order them by matching quality (1..4).
4. Within same quality, prefer non-template over template.
![Page 20: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/20.jpg)
Example 1
20
#include <iostream>
#include <typeinfo>
void foo(int x) { std::cout << "foo(int)\n"; } void foo(double x) { std::cout << "foo(double)\n"; } template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 21: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/21.jpg)
Example 1
21
#include <iostream>
#include <typeinfo>
void foo(int x) { std::cout << "foo(int)\n"; } void foo(double x) { std::cout << "foo(double)\n"; } template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 22: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/22.jpg)
Example 3
22
#include <iostream>
#include <typeinfo>
//void foo(int x) { // std::cout << "foo(int)\n"; //} void foo(double x) { std::cout << "foo(double)\n"; } template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 23: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/23.jpg)
Example 3
23
#include <iostream>
#include <typeinfo>
//void foo(int x) { // std::cout << "foo(int)\n"; //} void foo(double x) { std::cout << "foo(double)\n"; } template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 24: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/24.jpg)
Example 2
24
#include <iostream>
#include <typeinfo>
void foo(int x) { std::cout << "foo(int)\n"; } //void foo(double x) { // std::cout << "foo(double)\n"; //} template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 25: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/25.jpg)
Example 2
25
#include <iostream>
#include <typeinfo>
void foo(int x) { std::cout << "foo(int)\n"; } //void foo(double x) { // std::cout << "foo(double)\n"; //} template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 26: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/26.jpg)
Example 3
26
Won’t compile with the flag: -Wconversion
#include <iostream>
#include <typeinfo>
void foo(int x) { std::cout << "foo(int)\n"; } //void foo(double x) { // std::cout << "foo(double)\n"; //} template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.2); foo("abcdef"); return 0; }
![Page 27: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/27.jpg)
Example 4
27
#include <iostream>
#include <typeinfo>
//void foo(int x) { // std::cout << "foo(int)\n"; //} void foo(double x) { std::cout << "foo(double)\n"; } template<typename T> void foo(T* x) { std::cout << "foo<" << typeid(T).name() << ">(T*)\n"; } int main() { foo(42); foo(42.0); foo("abcdef"); return 0; }
Will compile with the flag: -Wconversion
![Page 28: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/28.jpg)
Example 5
28
template<typename T> void f(T x, T y) {
cout << "Template" << endl;}
void f(int w, int z) {
cout << "Non-template" << endl;}
int main(){ f( 1 , 2 ); f('a', 'b'); f( 1 , 'b');}
![Page 29: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/29.jpg)
Example 6
29
template<typename T> void f(T x, T y) {
cout << "Template" << endl;}
void f(int w, int z) {
cout << "Non-template" << endl;}
int main(){
f( 2 , 1.0);
f( 2.0 , 1.0);}
![Page 30: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/30.jpg)
30
template <typename T> void f(T) { cout << "Less specialized");} template <typename T> void f(T*) { cout<< "More specialized");} int main() { int i =0; int *pi = &i; f(i); // Calls less specialized function. f(pi); // Calls more specialized function. }
Is there a type that fits 1 and will not fit 2? If so, 2 is
more specialized and should be preferred.
1
2
Example 7
![Page 31: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/31.jpg)
Interim summary
31
• We saw template method• Declaration + Definition• Instantiation
•Now we will see a template class
![Page 32: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/32.jpg)
String Stack
32
class StrStk { public: StrStk():m_first(nullptr) { } ~StrStk() { while (!isEmpty()) pop(); } void push (string const& s ) {m_first=new Node(s,m_first);} bool isEmpty() const {return m_first==nullptr;} const string& top () const {return m_first->m_value;} void pop ()
{Node *n=m_first; m_first=m_first->m_next; delete n;} private: StrStk(StrStk const& rhs); StrStk& operator=(StrStk const& rhs);
struct Node { string m_value; Node* m_next; Node(string const& v ,Node* n):m_value(v),m_next(n) { } }; Node* m_first; };
![Page 33: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/33.jpg)
Generic Classes
33
• The actual code for maintaining the stack has nothing to do with the particulars of the string type.
• Can we have a generic implementation of stack?
![Page 34: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/34.jpg)
Generic Stack (Stk.hpp)
34
template <typename T> class Stk { public: Stk():m_first(nullptr) { } ~Stk() { while (!isEmpty()) pop(); } void push (T const& s ) {m_first=new Node(s,m_first);} bool isEmpty() const {return m_first==nullptr;} const T& top () const {return m_first->m_value;} void pop ()
{Node *n=m_first; m_first=m_first->m_next; delete n;} private: Stk(Stk const& rhs); Stk& operator=(Stk const& rhs); struct Node { T m_value; Node* m_next; Node(T const& v ,Node* n):m_value(v),m_next(n) { } }; Node* m_first; };
![Page 35: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/35.jpg)
Class Templates
35
template<typename T> class Stk { ... };
Stk<int> intList; // T = int Stk<string> stringList; // T = string
![Page 36: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/36.jpg)
Class Templates
36
The code is similar to non-template code, but:
• Add template<…> statement before the class
definition• Use template argument as type in class definition• To implement methods outside the class definition
(but still in header: .h.hpp, not in a cpp file!):
template <typename T> bool Stk<T>::isEmpty() const { return m_first==nullptr; }
![Page 37: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/37.jpg)
37
Example of generic programming - Iterators
![Page 38: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/38.jpg)
Constructing a List
38
• We want to initialize a stack from an array
• We can write a method that receives a pointer to the array, and a size argument
int arr[] = { 1, 2, 3, 4, 5, 6 }; Stk<int> stk; stk.push(arr, arr+sizeof(arr)/sizeof(*arr) );
• Alternative: use a pointer to initial position and one to the
position after the last:
stk.push(arr, arr+sizeof(arr)/sizeof(*arr) ); This form is more flexible (as we shall see)
![Page 39: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/39.jpg)
Constructing a List
39
// Fancy copy from array template< typename T > Stk<T>::push(const T* begin, const T* end) { for(const T* p=begin; p!=end; ++p) {
push(*p);
}}
![Page 40: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/40.jpg)
Constructing a List
40
// Fancy copy from array template< typename T > Stk<T>::push(const T* begin, const T* end) { for(; begin!=end; ++begin) {
push(*begin);
}}
![Page 41: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/41.jpg)
Pointer Paradigm
41
Code like:
const T* begin=arr;
const T* end= arr+sizeof(arr)/sizeof(*arr);
for(; begin!=end; ++begin) { // Do something with *begin } • Applies to all elements in [begin,end-1]• Common in C/C++ programs• Can we extend it to other containers?
![Page 42: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/42.jpg)
Iterator
42
• Object that behaves just like a pointer (or “weak” pointer)
• Allows to iterate over elements of a container
Example:
Stk<int> L; ...Stk<int>::iterator i; for( i = L.begin(); i != L.end(); i++ )
cout << " " << *i << "\n";
![Page 43: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/43.jpg)
Iterators
43
To emulate pointers, we need:
1. copy constructor
2. operator= (copy)
3. operator== (compare)
4. operator* (access value)
5. operator++ (increment)
And maybe:
6. operator[] (random access)
7. operator+= / -= (random jump)
8. ...
![Page 44: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/44.jpg)
Stk<T> iterator
44
Create an inner class, keep a pointer to a node.
class iterator { private: Node *m_pointer; }; Provides encapsulation, since through such an iterator we
cannot change the structure of the list
![Page 45: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/45.jpg)
Stk.hpp
45
![Page 46: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/46.jpg)
Initializing a Stk
46
We now want to initialize a stack from using parts of another stack. Something like:
Stk(iterator begin, iterator end) { for(; begin!=end; ++begin) { push(*begin); }}
![Page 47: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/47.jpg)
Initializing a Stk
47
Compare:
Stk(iterator begin, iterator end) { for(; begin!=end; ++begin) { push(*begin); }}To:
template< typename T > Stk<T>::push(const T* begin, const T* end) { for(; begin!=end; ++begin) {
push(*begin);
}}
![Page 48: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/48.jpg)
Generic Constructor
48
The code for copying using T* Stk<T>::iterator
are essentially identical on purpose --- iterators mimic pointers!
Can we write the code once?
Yes: Stk.hpp
![Page 49: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/49.jpg)
49
Template Variations
![Page 50: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/50.jpg)
Template Variations
50
Can receive several arguments
template <typename T1, typename T2> class A { T1 _d; T2 _c; }; int main() { A<double, int> a; }
![Page 51: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/51.jpg)
Template Variations
51
Can receive constant integral arguments
template< typename T, int Size> class Buffer { private: T m_values[Size]; };
Buffer<char,1024> Buff2; Buffer<int, 256> Buff3;
![Page 52: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/52.jpg)
Template Variations
52
Can set up default values for arguments
template<typename T=char, int Size = 1024> class Buffer { private: T m_values[Size]; }; Buffer<char> Buff1; Buffer<> Buff2; // same as Buff1 Buffer<int, 256> Buff3;
![Page 53: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/53.jpg)
Template and Types
53
• Buffer is not a type • Buffer<char,1024> is a type• Buffer<char>, buffer<char,1024>
are two names for the same type• Buffer<char,256> is a different type
![Page 54: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/54.jpg)
Template Variations
54
template <typename T, T val>class A { public: void foo() { std::cout << val << std::endl; }
};
int main() { A<int,7> a; A<char,'h'> b; // A<char,7.8> c; // compilation error a.foo(); b.foo(); }
//output7h
The placeholder type can be used in the types list:
![Page 55: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/55.jpg)
Template Variations
55
Can evaluate the type:
template <typename T> void foo(T* p) { } int main() { int d; foo(&d); // foo(int *) will be expand
// and called (T = int) }
![Page 56: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/56.jpg)
Template Variations
56
template <typename T> void foo(LinkedList<T*> list) {...}
int main() { LinkedList<int*> l1; LinkedList<LinkedList<int>* > l2; foo(l1); // T = int foo(l2); // T = LinkedList<int>}
![Page 57: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/57.jpg)
Template Variations
57
template <typename T> void foo(LinkedList<T*> list) {...}
template <typename T>void zoo(LinkedList<LinkedList<T>*> list) {...}
int main() { LinkedList<int*> l1; LinkedList<LinkedList<int>* > l2; foo(l1); // T = int foo(l2); // T = LinkedList<int> zoo(l2); // T = int}
![Page 58: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/58.jpg)
58
Template Specialization
![Page 59: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/59.jpg)
Template specialization
59
template <typename Type> class A { public: Type _data; A(const Type& data)
: _data(data) { } bool isBigger
(const Type& data) const; };
template <typename Type> bool A<Type>::isBigger
(const Type& data) const { return data > _data; }
int main() { A<char*> a("hi");
std::cout << a.isBigger("bye"); }
![Page 60: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/60.jpg)
Template specialization
60
template <typename Type> class A { public: Type _data; A(const Type& data)
: _data(data) { } bool isBigger
(const Type& data) const; };
template <typename Type> bool A<Type>::isBigger
(const Type& data) const { return data > _data; }
template <> bool A<char*>::isBigger(const char*& data) const { return strcmp(data, _data) > 0; }
int main() { A<int> ai(5); A<char*> as("hi"); ai.isBigger(7); //generic isBigger() as.isBigger("bye"); //specific isBigger() }
![Page 61: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/61.jpg)
Template specialization
61
template <typename Type> class A { public: Type _data; A(const Type& data)
: _data(data) { } bool isBigger
(const Type& data) const; };
template <typename Type> bool A<Type>::isBigger
(const Type& data) const { return data > _data; }
template <> bool A<char*>::isBigger(const char*& data) const { return strcmp(data, _data) > 0; }
int main() { A<int> ai(5); A<char*> as("hi"); ai.isBigger(7); //generic isBigger() as.isBigger("bye"); //specific isBigger() }
Although this is a classic example of template specialization, it is not clear that this is a good example as we change the behavior of the function!
An example of a problem with these kinds of template specialization: vector<bool> in the standard library.
A better example will be that we just change the time complexity.
![Page 62: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/62.jpg)
swap specialization
62
![Page 63: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/63.jpg)
Template specialization: checking types at compile time:
63
template <typename TNom,typename TDen> struct ErrorOnDivide { enum { ProblemToDivideByZero= 1, NonDivideable = 1 }; }; template <> struct ErrorOnDivide<int,int> { enum { ProblemToDivideByZero= 1, NonDivideable = 0 }; };
template <> struct ErrorOnDivide<double,double> { enum { ProblemToDivideByZero= 0, NonDivideable = 0 }; };
![Page 64: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/64.jpg)
64
template <typename TNom, typename TDen, typename TRes > void SafeDiv(const Tnom& nom, const Tden& den, TRes& res) { // static_assert only in c++11 (supported in current compilers) static_assert( ErrorOnDivide<TNom,TDen>::ProblemToDivideByZero==0 && ErrorOnDivide<TNom,TDen>::NonDivideable==0, "Division not safe"); res=nom/den; }
int main() { double res; SafeDiv(10.0,3.0,res); //OK SafeDiv(10,3,res); //Compilation Error "division not safe" }
Template specialization: checking types at compile time:
![Page 65: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/65.jpg)
Template Meta-Programming
65
// primary template to compute 3 to the Nthtemplate<int N>class Pow3 {public:enum { result=3*Pow3<N-1>::result };};// full specialization to end the recursiontemplate<>class Pow3<0> {public:enum { result = 1 };};int main(){ std::cout << Pow3<1>::result<<"\n"; //3 std::cout << Pow3<5>::result<<"\n"; //243 return 0;}
![Page 66: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/66.jpg)
The typename keyword - reminder (1)
66
template <class T> class A { public: T _data; A(T data)
:_data(data) { } };
template <typename T>
class A { public: T _data; A(T data) : _data(data) { } };
Another keyword to define type parameters in templates
![Page 67: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/67.jpg)
The typename keyword (2)
67
Resolve "ambiguity":
template<typename T> class X { T::Y * _y;
}; int main() { } // sometimes compilation error
![Page 68: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/68.jpg)
The typename keyword (3)
68
Resolve "ambiguity":
template<typename T> class X { typename T::Y * _y; // treat Y as a type }; int main() { }
// OK
![Page 69: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/69.jpg)
The typename keyword (4)
69
template <typename T> T inner_product (const vector<T>& v1, const vector<T>& v2) { T res= 0; typename vector<T>::const_iterator iter1; typename vector<T>::const_iterator iter2; for (iter1= v1.begin(), iter2= v2.begin(); iter1!=v1.end(); ++iter1,++iter2) {
assert(iter2!=v2.end()); res+= (*iter1) * (*iter2); } assert(iter2==v2.end()); return res; }
![Page 70: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/70.jpg)
C++11 no need for typename
70
template <typename T> T inner_product (const vector<T>& v1, const vector<T>& v2) { T res= 0; auto iter1= v1.cbegin(); auto iter2= v2.cbegin(); for ( ; iter1!=v1.cend(); ++iter1,++iter2) {
assert(iter2!=v2.cend()); res+= (*iter1) * (*iter2); } assert(iter2==v2.cend()); return res; }
![Page 71: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/71.jpg)
Inner product is actually in the standard library and is more general…
71
![Page 72: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/72.jpg)
Templates - recap
72
1. Compile time polymorphism / meta programing – do whatever possible in compilation instead of run time.
2. Arguments are types or integral constants.
3. Efficient but large code.
4. Longer compilation time (but precompiled header can help)
![Page 73: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/73.jpg)
Longer compilation time is not always a bad thing (from xkcd):
73
![Page 74: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/74.jpg)
Polymorphism vs. Templates
74
• Templates compilation time is much longer than using inheritance.
• Using templates enlarge the code size.• Compilation errors can be very confusing.
• Templates running time is much faster than using inheritance.
• Combined with inlining, templates can reduce runtime overhead to zero.
![Page 75: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/75.jpg)
Polymorphism vs. Templates
75
• Templates allow static (compile-time) polymorphism, but not run-time polymorphism.
• You can actually combine them.
• As always – think of your task.
![Page 76: Templates. Before we dive in 2 Preprocessing Compilation Linkage](https://reader030.vdocument.in/reader030/viewer/2022032607/56649eba5503460f94bc25d6/html5/thumbnails/76.jpg)
Summary
76
• Compile-time mechanism to polymorphism
• It might help to write & debug concrete example (e.g., intList) before generalizing to a template
• Understand iterators and other “helper” classes
• Foundation for C++ standard library