Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging.

Similar presentations


Presentation on theme: "CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging."— Presentation transcript:

1 CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging it into functions We’ve also looked at object-oriented programming –Reuse of code and data by packaging them into classes However, these techniques alone have limitations –Functions are still specific to the types they manipulate E.g., swap (int, int) and swap (int *, int *) do essentially same thing But, we must write two versions of swap to implement both –Classes alone are still specific to the types they contain E.g., keep an array (not a vector) of dice and an array of players –Must write similar data structures and code repeatedly E.g., adding a new element to an array Generic programming aims to relieve these limitations

2 CSE 332: C++ templates and generic programming I C++ STL Generic Programming Example #include using namespace std; int main (int, const char **) { int numbers [] = {0, 9, 2, 7, 4, 5, 6, 3, 8, 1}; size_t array_dimension = sizeof (numbers) / sizeof (int); // prints out 0 1 2 3 4 5 6 7 8 9 (ascending sort) sort (numbers, numbers + array_dimension); copy (numbers, numbers + array_dimension, ostream_iterator (cout, " ")); cout << endl; // prints out 9 8 7 6 5 4 3 2 1 0 (descending sort) sort (numbers, numbers + array_dimension, greater ()); copy (numbers, numbers + array_dimension, ostream_iterator (cout, " ")); cout << endl; // prints out 5 6 2 1 9 4 7 8 3 0 (shuffled) random_shuffle (numbers, numbers + array_dimension); copy (numbers, numbers + array_dimension, ostream_iterator (cout, " ")); cout << endl; return 0; } native container type (array) callable object native iterator type (pointer) user-defined iterator type calls to STL algorithms Iterator constructor calls

3 CSE 332: C++ templates and generic programming I Decoupling Data Types from Algorithms The C++ STL has an architectural separation of concerns –Containers hold data of a particular type –Iterators give access to ranges of data –Algorithms operate on particular kinds of iterators –Callable objects plug in functions to modify algorithms Containers include arrays, vector, list, set Iterators include pointers, ostream_iterator Algorithms include sort, copy, random_shuffle Callable objects include less, greater

4 CSE 332: C++ templates and generic programming I Decoupling Data Types from Algorithms (cont.) Iterators decouple algorithms from containers –Algorithms require specific iterator interfaces –Containers provide iterators that give specific interfaces –Allows safe combinations, disallows unsafe/inefficient ones E.g., algorithm can use ++ for iterator over linked list or array E.g., algorithm can only use [ ] or += for iterator over array (not list) Callable objects decouple algorithms’ sub-steps –E.g., algorithms like sort use a comparison function –Sorting is valid for a variety of different comparisons And may give different results for each of them –Allowing different comparison functions to be plugged in Lets the sort default to producing an ascending order Lets a different callable be plugged in to produce a descending order

5 CSE 332: C++ templates and generic programming I Supporting Native and User Defined Types Native arrays provide a natural container abstraction –Hold a (contiguous) range of elements –Can access the values at different positions –Can change the values at different positions –With pointers, new, and delete, can even re-dimension them Native pointers provide a natural iterator abstraction –Point to a position in a container (e.g., an array) –Can move from one position to the next (e.g., ++, +=) –Can be dereferenced to obtain the value at aliased location Since C++ STL can’t change how native types work –It uses arrays and pointers as a container/iterator example –It ensures that user-defined containers/iterators are similar –Pointers support all operations any STL iterator must provide

6 CSE 332: C++ templates and generic programming I Support for Generic Programming in C++ The power of C++ generics comes from 3 main ideas –Decoupling data types from algorithms operating on them –Seamlessly supporting both native and user defined types –Templates: type parameterization, interface polymorphism Templates introduce type parameterization –Allows you to write functions like swap once … … and then plug in parameter types as needed –Allows you to write class templates … … and then plug in member variable types later –This already allows a great deal of flexibility, e.g., list intlist; list stringlist; where list is a template, and int and string are used as type parameters to different instantiations of that template Templates introduce interface polymorphism –Templates impose type requirements on their parameters –Can plug in any types for which template’s syntax is valid

7 CSE 332: C++ templates and generic programming I Templates: Crucial to C++ Generic Programming Templates are used to parameterize classes and functions with different types –Function templates do not require explicit declaration of parameterized types when called E.g., swap (i, j); –Classes require explicit declaration of parameterized types when instantiated E.g., vector v; Some compilers require that template definitions be included with declarations

8 CSE 332: C++ templates and generic programming I Function Templates template void swap(T & lhs, T & rhs) { T temp = lhs; lhs = rhs; rhs = temp; } int main () { int i = 3; int j = 7; long r = 12; long s = 30; swap (i, j); // i is now 7, j is now 3 swap (r, s); // r is now 30, s is now 12 return 0; } The swap function template takes a single type parameter, T –interchanges values of two passed arguments of the parameterized type Compiler instantiates the function template twice in main –with type int for the first call –with type long for the second call –Note that the compiler infers the type each time swap is called –Based on the types of the arguments

9 CSE 332: C++ templates and generic programming I Another Function Template Example STL-style linear search (based on Austern pp. 13): template Iterator find2 (Iterator first, Iterator last, const T & value) { while (first != last && *first != value) { ++first; } return first; } Our first generic algorithm –Searches any one-dimensional sequence of elements –“Not found” is a normal result, does not throw exception Returns position last : just past the end of the range [ first, last )

10 CSE 332: C++ templates and generic programming I Class Templates template class Array { public: Array(const int size); ~Array(); const int size () const; private: T * m_values; const int m_size; }; int main (int, char**) { Array a(10); return 0; } Start with a simple declaration –Which we’ll expand as we go Notice that parameterized type T is used within the class template –Type of pointer to array When an instance is declared, must also explicitly specify the concrete type parameter –E.g., int in function main (int, char**)

11 CSE 332: C++ templates and generic programming I Class Templates and Inheritance class ArrayBase { public: ArrayBase(const int size); ~ArrayBase(); const int size () const; protected: const int m_size; }; template class Array : public ArrayBase { public: Array(const int size); ~Array(); private: T * m_values; }; Class templates can inherit from base classes –Or class templates, but must relate type parameters to those of base Here, we’ve separated template and non-template code –Non-template base class –Template derived class –Functions and variables that do not need to refer to type parameters go into the base class This is useful in many cases –To avoid accidental type errors (ArrayBase doesn’t access T) –To reduce program size (separate method definitions compiled for Array Array etc.)

12 CSE 332: C++ templates and generic programming I Templates Introduce Interface Polymorphism Can plug in any types for which template’s syntactic use is valid (get a compiler error if not) –Templates apply to types that provide a common interface –What needs to be common depends on the template Templates impose requirements on type parameters –Each requirement consists of a C++ expression that must be valid for that types involved in that expression e.g., if a template’s code has Z z; Z must allow default construction Interface polymorphism still allows Liskov Substitution –If S models a subset of the requirements modeled by T then wherever you need an S you can plug in a T –Much more on this in the next several lectures


Download ppt "CSE 332: C++ templates and generic programming I Motivation for Generic Programming in C++ We’ve looked at procedural programming –Reuse of code by packaging."

Similar presentations


Ads by Google