Presentation is loading. Please wait.

Presentation is loading. Please wait.

“Generic Programming” ECE 297

Similar presentations


Presentation on theme: "“Generic Programming” ECE 297"— Presentation transcript:

1 “Generic Programming” ECE 297
Templates “Generic Programming” ECE 297

2 Templates A way to write code once that works for many different types of variables float, int, char, string, List, Vector, … Reference: Problem Solving in C++ by Savitch, Chapter 17

3 Template Functions

4 Types & Functions All parameters and local variables in a function must have a type void swap_val (int &a, int &b) { int temp; temp = a; a = b; b = temp; } void swap_val (double &a, double &b) double temp; OK. Function overloading

5 Function Templates Allow you to write “abstract algorithms”
Work for many types template<class VariableType> void swap_val (VariableType &a, VariableType &b) { VariableType temp; temp = a; a = b; b = temp; } “template prefix” defines a type parameter Can use that “type parameter” instead of a regular type In the function

6 Using a Function Template
template<class VariableType> void swap_val (VariableType &a, VariableType &b) { VariableType temp; temp = a; a = b; b = temp; } int main () { int i1 = 5, i2 = 10; swap_val (i1, i2); // Compiler will create swap_val<int> float f1 = 1e6, f2 = 2e6; swap_val (f1, f2); // Compiler will create swap_val<float> Template definition must come before template use

7 Using a Function Template
swap_val.h template<class VariableType> void swap_val (VariableType &a, VariableType &b) { VariableType temp; temp = a; a = b; b = temp; } main.cpp #include “swap_val.h” int main () { int i1 = 5, i2 = 10; swap_val (i1, i2); // swap_val<int> created float f1 = 1e6, f2 = 2e6; swap_val (f1, f2); // swap_val<float> created }

8 Restrictions on Swap   
template<class VariableType> void swap_val (VariableType &a, VariableType &b) { VariableType temp; temp = a; a = b; b = temp; } swap_val (int, int); swap_val (char, char); swap_val (List, List); Works for any one type that has proper (deep copy) operator=

9 Generic Minimum template<class VariableType> VariableType minimum (VariableType a, VariableType b) { if (a < b) return (a); else return (b); } minimum (int, int); minimum (float, float); minimum (int, float); minimum (int[20], int[20]); minimum (List, List); minimum (string, string); Works for any one type that defines operator< (reasonably) Demo syntax errors here – int, float. How to read & debug. Must be one type Compiles but Operator< compares pointers Operator< undefined

10 Template Classes

11 Template Classes Can make templated (type-generic) classes
Member functions Member data Most useful for container classes Classes that implement basic data structures List, Vector, Tree (Map), …

12 Example: Pair of Data Often useful to store two pieces of data together key, value in ECE 244 lab5 (binary tree for DNS) used together string name, int ip (244 lab 5) Could want: string name, string data or int key, float data Make a class that can store two arbitrary pieces of data first (any type) second (any type)

13 Generic Pair Class template<class Tfirst, class Tsecond> class MyPair { public: MyPair (Tfirst _first, Tsecond _second); void setFirst (Tfirst _first); void setSecond (Tsecond _second); Tfirst getFirst (); Tsecond getSecond (); private: Tfirst first; Tsecond second; }; In MyPair.h

14 Generic Pair Class #include “MyPair.h” int main () { MyPair<int,float> pair1(1, 2.5); cout << pair1.getFirst() << “ “ << pair1.getSecond(); ... In main.cpp Creates a variable named pair1 class (type) is MyPair<int, float> pair1 int first = 1 float second = 2.5

15 Generic Pair Class #include “MyPair.h” int main () { MyPair<int,float> pair1(1, 2.5); cout << pair1.getFirst() << “ “ << pair1.getSecond(); MyPair<string,double> tscore ("Your test score", 7.5); cout << tscore.getFirst() << " " << tscore.getSecond() << endl; tscore.setFirst ("Revised test score"); tscore.setSecond (9.5); cout << tscore.getFirst() << " " << tscore.getSecond() << endl; } In main.cpp Creates a variable named tscore class (type) is MyPair<string, double> tscore string first = “Your test score” double second = 7.5

16 Generic Pair Class #include “MyPair.h” int main () { MyPair<int,float> pair1(1, 2.5); cout << pair1.getFirst() << “ “ << pair1.getSecond(); MyPair<string,double> tscore ("Your test score", 7.5); cout << tscore.getFirst() << " " << tscore.getSecond() << endl; tscore.setFirst ("Revised test score"); tscore.setSecond (9.5); cout << tscore.getFirst() << " " << tscore.getSecond() << endl; } In main.cpp Program output 1 2.5 Your test score 7.5 Revised test score 9.5

17 Writing Templates Write code for a specific type first
Debug, test Convert to template Can get complex / subtle syntax errors

18 Recap Template functions Template classes
E.g. minimum(T a, T b) Template classes E.g. generic pair: pair<int,string> Standard template library (STL) Useful algorithms: E.g. min, max, avg Useful data structures: E.g. vector<int>

19 STL: Generic Algorithms
Using the Standard Template Libraries

20 STL Writing templates  fairly hard Using templates easy & productive
Standard Template Library Fast, well-tested implementations of useful algorithms and data structures

21 STL: Generic Algorithms
Useful algorithms that work with many types in <algorithm> template<class T> T max (T a, T b) { if (a < b) return (b); else return (a); } <algorithm> #include <algorithm> using namespace std; int main ( ) { double x = 1.1, y = 1.2; double z = max (x, y); int j = 2, k = 3; int i = max (j, k); z = max (i, x); z = max (x, 2); z = max (x, 2.0); } main.cpp // OK  max (int, int) // Won’t compile // Won’t compile // OK! max (double, double)

22 STL: Generic Algorithms
Also in <algorithm>: min (), sort () Work for any one type that defines < and assignment (operator=) and lots more – see cplusplus.com But I only use the very basic ones

23 STL Container Classes

24 STL: Container Classes
Most useful part of STL Data structures that just “contain” some other data type / class E.g. vector, linked list, binary tree of some type Can use to store any type of data (templated) Avoids a lot of repetitive coding of linked lists, binary trees, etc.

25 Vector Example motivation:
Want to read integers from cin to an array until EOF > <Ctrl+D> Then pass the array on to the rest of the program to process, print, examine, … Problem: how big an array should we allocate? int *array = new int[??]; Don’t know until after the input is read! Could code up a linked list, load it, count elements, then allocate array, copy data from linked list, delete linked list

26 Vector Wouldn’t it be great to have something just like an array that could grow as needed? #include <vector> #include <iostream> using namespace std; vector<int> get_input ( ) { vector<int> vec; // vector of ints, initially empty int val; cin >> val; while ( !cin.fail() ) { vec.push_back (val); // Add new value to end of vector } return (vec); // Return the whole vector main.cpp

27 Vector: Can Use Like Array
#include <vector> #include <iostream> using namespace std; . . . int main () { vector<int> in_vals; in_vals = get_input (); for (int i = 0; i < in_vals.size(); i++) cout << in_vals[i] << “ “; cout << endl; for (int i = in_vals.size() – 1; i >= 0; i--) } main.cpp vectors know how many elements they contain. Valid data from index 0 to size()-1 Fast, O(1), random access to any entry How would I print out the vector in reverse order? Input: <Ctrl+D> Output:

28 Slightly Cleaner Version
int main () { vector<int> in_vals; in_vals = get_input (); for (int i = 0; i < in_vals.size(); i++) cout << in_vals[i] << “ “; } Compiler will give a type mismatch warning (.size() is actually a 64-bit unsigned int). Harmless, but I prefer to have no warnings. Using the exact right type of unsigned int – warning will go away for (size_t i = 0; i < in_vals.size(); i++) cout << in_vals[i] << “ “;

29 How Does It Work? vector<int> get_input ( ) {
vector<int> vec; // vector of ints, initially empty int val; cin >> val; while ( !cin.fail() ) { vec.push_back (val); // Add new value to end of vector } return (vec); // Return the whole vector 1 vec 1 -20 int *array int size int capacity 1 5 2 3 4 8 2 1 4 1 -20 3 31 Input: 1 -20 3 31 55 1 -20 3 31 55

30 Vector: Key Properties
Efficient to add elements at end (push_back) Because when there isn’t enough space it grows the storage quite a bit (usually 2x) Means even for a large number N of push_back(), we get only a few array copies O(1) on average Efficient random access to data Because internally the vector stores the data in an array  operator[ ] can be fast O(1)

31 Handy Constructors #include <vector> using namespace std;
int main () { vector<int> vec1; // default constructor: size = 0 vector<int> vec2(10); // size = 10, default value (0) vector<int> vec3(10,-1); // size = 10, all values -1 }

32 Assignment & Destruction
#include <vector> using namespace std; int main () { int *a = new int[10]; int *b = new int[10]; vector<int> v1(10), v2(10); a[0] = 2; v1[0] = 2; . . . a = b; // OK? v1 = v2; // OK? delete[] a; delete[] b; delete v1; // Should I? } No! Shallow copy Yes! Proper deep copy defined in <vector> No! <vector> defines a destructor; cleans up its internal array

33 operator[] #include <vector> using namespace std; int main () {
vector<int> v1; v1.push_back(-3); v1[0] = -2; // OK? v1[1] = -2; // OK? v1.push_back(-3); // OK? v1[1] = -2; // OK? } Yes, entry 0 exists No, can’t create values with [ ] Demo here: show what compiles, what seg faults, how you get a good error with the debug flag. (g++ -D_GLIBCXX_DEBUG) Yes, can create values with push_back() Yes, entry 1 exists now Really bad  out of bounds array access and memory corruption (maybe seg fault, maybe worse!) Most compilers have an option to make vector check the [ ] index value is between 0 and size()-1 and print an error Slows program down  we have turned this on only for the DebugCheck configuration of your milestone1 NetBeans project

34 Shrinking a vector #include <vector> using namespace std;
int main () { vector<int> v1; v1.push_back(1); v1.push_back(2); for (int i = 0; i < in_vals.size(); i++) cout << in_vals[i] << “ “; v1.pop_back(); // Removes one entry from end of vector } Output: 1 2 Output: 1

35 Vectors should be familiar
vector<char> almost same as <string> Difference: string defines some extra utility functions Otherwise a string really is a vector<char> Full reference on vector member functions at

36 Compiler supports C++11 standard so OK to use these recent features
STL References Basic Reference: “Problem Solving in C++” by Savitch, Chapter 18 Detailed reference: cplusplus.com Compiler supports C++11 standard so OK to use these recent features Really nitty gritty details: “C++ Primer” by Lippman, Lajoie and Moo

37 Recap Template functions Template classes
E.g. minimum(T a, T b) Template classes E.g. generic pair: pair<int,string> Standard template library (STL) Useful algorithms: E.g. min, max, avg Useful data structures: E.g. vector<int> Next time: more STL data structures Very useful for course (and after!)


Download ppt "“Generic Programming” ECE 297"

Similar presentations


Ads by Google