Download presentation
Presentation is loading. Please wait.
Published byAlan Craig Modified over 9 years ago
1
Generic Programming in C++
2
Generic Parameters Function for squaring a number: Function for squaring a number: sqrt(x) { return x * x; } C version: C version: int sqrt(int x) { return x * x; } Multiple versions: Multiple versions: int sqrtInt(int x) { return x * x; } C++ overloading: C++ overloading: int sqrt(int x) { return x * x; } double sqrt(double x) { return x * x; }
3
C++ Templates template template T sqrt(T x) { return x * x; } Compiler automatically generates a version for each parameter type used by a program: Compiler automatically generates a version for each parameter type used by a program: int a = 3; double b = 3.14; int aa = sqrt(a); double bb = sqrt(b);
4
Notes: macros’ limits #define sqrt(x) ((x) * (x)) int aa = sqrt(a++); int aa = ((a++) * (a++)); int aaa = sqrt(aa); #define fact(n) (n == 0) ? 1 : fact(n-1) * n #define SQRT(T) T sqrt(T x) {return x * x; } SQRT(int);SQRT(double);sqrt(a);sqrt(b);
5
Other types as well? class Complex { double real, imag; Complex operator *(Complex y) { return Complex( real * y.real – imag * y.imag, real * y.imag + imag * y.real); } Complex c(1, 2); Complex cc = sqrt(c);
6
Compile time checking template template void swap(T& a, T& b) { const T temp = a; a = b; b = temp; } int a = 5, b = 9; swap(a, b);// OK double c = 9.0; swap(a, c);// error
7
C++ Standard Template Library Goal: represent algorithms in as general form as possible without compromising efficiency Goal: represent algorithms in as general form as possible without compromising efficiency Extensive use of templates Extensive use of templates Only uses static binding (an inlining) Only uses static binding (an inlining) Use of iterators for decoupling algorithms from containers Use of iterators for decoupling algorithms from containers Iterator: abstraction of pointers Iterator: abstraction of pointers
8
STL Organization Containers Containers –vector, deque, list, set, map, … Algorithms Algorithms –for_each, find, transform, sort Iterators Iterators –forward_iterator, reverse_iterator, istream_iterator, … Function Objects Function Objects –plus, equal, logical_and, project1 Allocators Allocators
9
Examples from C++ Annotations vector vector inner_product inner_product sort sort
10
Forward Iterator int main(int argc, char **argv) { vector args(argv, argv + argc); vector args(argv, argv + argc); vector ::iterator iter = args.begin(); vector ::iterator iter = args.begin(); for ( ; iter != args.end(); ++iter ) for ( ; iter != args.end(); ++iter ) cout << *iter << " "; cout << endl; cout << endl;
11
Reverse Iterator vector ::reverse_iterator iter = args.rbegin(); vector ::reverse_iterator iter = args.rbegin(); for (; iter != args.rend(); ++iter ) for (; iter != args.rend(); ++iter ) cout << *iter << " "; cout << endl; cout << endl;
12
Inner Product unsigned ia1[] = {1, 2, 3, 4, 5, 6, 7}; unsigned ia2[] = {7, 6, 5, 4, 3, 2, 1}; cout << "The sum of all squares in "; copy(ia1, ia1 + 7, ostream_iterator (cout, " ")); cout << "is: “; int init = 0; cout << inner_product(ia1, ia1 + 7, ia1, init) << endl; cout << "The sum of all cross-products in "; copy(ia1, ia1 + 7, ostream_iterator (cout, " ")); cout << " and "; copy(ia2, ia2 + 7, ostream_iterator (cout, " ")); cout << "is: “; init = 0; cout << inner_product(ia1, ia1 + 7, ia2, init) << endl;
13
inner_product: definition T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryFunction1 binary_op1, BinaryFunction2 binary_op2); Initializes result to init Initializes result to init For each iterator i in [first1, last1), updates result as follows: For each iterator i in [first1, last1), updates result as follows: result = binary_op1(result, binary_op2(*i, *(first2 + (i - first1))).
14
Inner Product (string concat) class Cat { class Cat { public: public: Cat(string const &sep): sep(sep) {} Cat(string const &sep): sep(sep) {} string operator()(string const& s1, string const& s2) { string operator()(string const& s1, string const& s2) { return (s1 + sep + s2); } return (s1 + sep + s2); } private: private: string sep; string sep; }; }; string names1[] = {"Frank", "Karel", "Piet"}; string names2[] = {"Brokken", "Kubat", "Plomp"}; cout << "A list of all full names in "; copy(names1, names1 + 3, ostream_iterator (cout, " ")); cout << "and "; copy(names2, names2 + 3, ostream_iterator (cout, " ")); cout << "is:" << inner_product(names1, names1 + 3, names2, string("\t"), Cat("\n\t"), Cat(" ")) << endl;
15
Parametrized Bubblesort template template class greater { public: bool operator()(const T& a, const T& b) const { return a > b; }; template template class less { public:bool operator()(const T& a, const T& b) const { return a < b; };
16
Note int x = 3, y = 5; bool b = greater ()(x, y);
17
Function object version template template void bubblesort(T a[], unsigned size, const C& comp) { for (unsigned i = 0; i < size; ++i) for (unsigned i = 0; i < size; ++i) for (unsigned j = i+1; j < size; ++j) for (unsigned j = i+1; j < size; ++j) if (comp(a[i], a[j])) swap(a[i], a[j]); };
18
Functional version template template void bubblesort(T a[], unsigned size, bool (*comp)(T&, T&)) { for (unsigned i = 0; i < size; ++i) for (unsigned i = 0; i < size; ++i) for (unsigned j = i+1; j < size; ++j) for (unsigned j = i+1; j < size; ++j) if (comp(a[i], a[j])) swap(a[i], a[j]); };
19
Bubblesort usage int x[] = {-1, -2, -3, -4, -5}; bubblesort(x, sizeof(x)/sizeof(x[0]), greater ()); bubblesort(x, sizeof(x)/sizeof(x[0]), less ());
20
Template Enumeration template template class TheVector { private: std::vector vector; public: Enumeration getEnumeration() { return (Enumeration(&vector)); } class Enumeration { … } };
21
Enumeration (2) class Enumeration { private: private: vector const* vp; vector const* vp; unsigned idx; unsigned idx; public: public: Enumeration(vector const* vector) : Enumeration(vector const* vector) : vp(vector), idx(0) { } vp(vector), idx(0) { } T const& nextElement() { // uses 'T‘ T const& nextElement() { // uses 'T‘ if (idx == vp->size()) if (idx == vp->size()) throw NoSuchElementException(index); throw NoSuchElementException(index); return (*vp)[idx++]; return (*vp)[idx++]; } bool hasMoreElements() { return idx size(); } bool hasMoreElements() { return idx size(); }};
22
Enumeration (3) TheVector theVector; … TheVector ::Enumeration en = theVector.getEnumeration(); while (en.hasMoreElements()) cout << en.nextElement() << endl;
23
Issue: template instantiation // file sumVector.h template template T sumVector(T* array, unsigned n) { T sum(0); for (int i = 0; i < n; ++i) sum += array[i]; sum += array[i]; return sum; }
24
Instantiation (1) #include "sumVector.h" int x[] = {1, 2}; double y[] = {1.1, 2.2}; cout << sumVector(x, 2) << endl << sumVector(y, 2) << endl; If the same template function definition is included in different source files, separately compiled and linked, there will be only one instantiation, per type of template function If the same template function definition is included in different source files, separately compiled and linked, there will be only one instantiation, per type of template function
25
Instantiation (2) declare a template function, if it is known that the required instantiation is available in another source file: declare a template function, if it is known that the required instantiation is available in another source file: template template T sumVector(T* tp, unsigned n); int v[] = {1, 2}; sumVector(v, 2);
26
Instantiation (3) declare template functions in header files, keep the definition in a template source file: declare template functions in header files, keep the definition in a template source file: template template T sumVector(T* tp, unsigned n) { return (*tp); return (*tp);} static void* p1 = static_cast (sumVector);
27
Forcing Instantiations static void* p[] = { static_cast (sumVector), static_cast (sumVector), static_cast (sumVector) static_cast (sumVector)};
28
Explicit Instantiations template template T sumVector(T *tp, unsigned n) { return (*tp); } template int sumVector (int *, unsigned); template double sumVector (double *, unsigned); template unsigned sumVector (unsigned *, unsigned);
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.