C Templates CS 247 Module 20 Scott Chen

  • Slides: 20
Download presentation
C++ Templates CS 247 Module 20 Scott Chen

C++ Templates CS 247 Module 20 Scott Chen

Assigned Readings Ø Eckel. Vol. 2 • Chapter 5 – template in Depth

Assigned Readings Ø Eckel. Vol. 2 • Chapter 5 – template in Depth

Agenda for Module 20 Ø Template Ø Design Considerations for Templates

Agenda for Module 20 Ø Template Ø Design Considerations for Templates

Section 1 Templates

Section 1 Templates

Templates – Function Templates Ø Problem • Codes in overloaded functions whose function bodies

Templates – Function Templates Ø Problem • Codes in overloaded functions whose function bodies are identical, except for the types of their arguments. Ø Solution • A Function Template can be used to describe a family of functions int compare ( const int& v 1, const int& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; } int compare ( const string& v 1, const string& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; } template <typename T> int compare ( const T& v 1, const T& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; } //Client Code compare ( 1, 3 ); // compare <int> compare ( 3. 14, 2. 7 ); // compare <double>

Templates - Instantiation Ø When the client programmer instantiates a template, the compiler generates

Templates - Instantiation Ø When the client programmer instantiates a template, the compiler generates and compiles a type-specific version of the template. int compare ( const int& v 1, const int& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; int compare ( const string& v 1, const string& v 2 ) } { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; int compare ( const double& v 1, const double& v 2 ) } { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; int compare ( const Thing& v 1, const Thing& v 2 ) } { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; } template <typename T> int compare ( const T& v 1, const T& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; }

Templates – Argument Deduction Ø If a template type parameter is used for more

Templates – Argument Deduction Ø If a template type parameter is used for more than one function parameters, the deduced types for the call arguments MUST match; otherwise compiler will throw an error. template <typename T> int compare ( const T& v 1, const T& v 2 ) { … } Ø Client Code: short si = 5; compare ( si, si ); Compare ( si, 20 ); // compare<short> // error – compiler cannot infer type

Templates – Function Template Example template <class Input. Iter, class Output. Iter, class Predicate>

Templates – Function Template Example template <class Input. Iter, class Output. Iter, class Predicate> Output. Iter copy_if ( Input. Iter first, Input. Iter last, Output. Iter result, Predicate pred ) { for ( ; first != last ; first++) if ( pred(*(first) ) *result++ = *first; return result; }

Templates – Class Template Ø Define a generic (parameterized) class • e. g. ,

Templates – Class Template Ø Define a generic (parameterized) class • e. g. , a container whose element type is specified by a parameter Ø Class Template Instantiation • The actual element type if determined by the argument for T. When instantiating a class template, the user must provide the template parameter – the compiler cannot infer this type. // Client Code Stack<string> ss; Stack<int> is; Stack<Figure*> fs; • The compiler generates a string- / int- / Figureversion of Stack by respectively substituting string / int / Figure* for T, and generate the corresponding code. template <typename T> class Stack{ public: Stack(); void push (const T&); T top() { return items_[ top_ ]; } void pop(); private: T items_ [STACK_SIZE]; int top_; }; template <typename T> void Stack<T>: : push(const T& elem) { ++top_; items_ [ top_ ] = elem; } …

Templates – Non-Type Template Parameters Ø Can have non-type template parameters, which are treated

Templates – Non-Type Template Parameters Ø Can have non-type template parameters, which are treated as compile-time constants. • Can provide a default value template <typename T, int size = 100> class Stack{ public: Stack(); void push (const T&); T top() { return items_[ top_ ]; } void pop(); private: T items_ [ size ]; int top_; }; • Client code provides a compile-time value for size: //Client Code Stack<int, 99> my. Stack 1; Stack<int> my. Stack 2; // Stack of size 99 // Stack of default size 100

Section 2 Template Design Considerations

Section 2 Template Design Considerations

Design Consideration - Friend Ø There are three kinds of friend declarations that may

Design Consideration - Friend Ø There are three kinds of friend declarations that may appear in a class template. Each kind of them declares friendship to one or more entities: 1. A friend declaration for an ordinary non-template class or function, which grants friendship to the specific named class or function. 2. A friend declaration for a class template or function template, which grants access to all instances of the friend. 3. A friend declaration that grants access only to a specific instance of a class or function template.

Design Consideration – “Duck Typing” Ø How the template definition uses variables of type

Design Consideration – “Duck Typing” Ø How the template definition uses variables of type T will impose some requirements on allowable instantiations: template <typename T> T mumble (T val){ T new. Val = val; T *p = nullptr; val. speak(); cout << “val = ” << val << endl; if ( val < new. Val ) return “success”; } T must be: 1) Comparable through operator< 2) Must be string-like

Design Consideration – Parameters Ø 1. How should parameters of Template Type be passed?

Design Consideration – Parameters Ø 1. How should parameters of Template Type be passed? • • Pass-by-Value Pass-by-Reference Appropriate for primitive types (why or why not? ) Appropriate for class types (why or why not? ) Ø 2. Consider the initialization of objects with parameterized members. template <typename T, typename U> struct pair { T first; // Parameterized Members U second; // Parameterized Members pair() : first{ T() }, second{ U() } {} pair ( const T &t, const U &u ) // copy constructor (by reference) : first { t }, second { u } {} template <typename V, typename W> pair ( const pair<V, W> &p ) // pass-by-reference for class type : first { p. first }, second { p. second } {} };

Design Consideration – Template Compilation 1. The Template definition is compiled first • If

Design Consideration – Template Compilation 1. The Template definition is compiled first • If the code might be legal for some type T, then the definition is considered to be legal. // file max. h template <typename T> T max (T a, T b) { return a > b ? a : b; } 2. When the template is instantiated, then the instantiated class / function is type-checked again // Client Code #include “max. h” #include “My. Object. h” … My. Object a{…}, b{…}; My. Object c = max<My. Object>(a, b)

Design Consideration – Template Compilation 3. The compiler must see the template definition in

Design Consideration – Template Compilation 3. The compiler must see the template definition in order to instantiate and compile the template • BDP: Include template definition in header file § Can also #include implementation to maintain separation of header and implement code // header file utilities. h #ifndef UTILITIES_H #define UTILITIES_H template <typename T> int compare( const T&, const T& ); // Other declarations #include “utilities. hpp” // get the definitions for compare etc. from implementation file #endif // implementation file utilities. hpp template <typename T> int compare( const T& v 1, const T& v 2 ) { if ( v 1 < v 2 ) return -1; if ( v 2 < v 1 ) return 1; return 0; } // Other Definitions

Design Consideration – C++11 Variadic Template Ø In C++11, templates can have a variable

Design Consideration – C++11 Variadic Template Ø In C++11, templates can have a variable number of template arguments • It’s left for you to explore this feature void print() { } // base case template <typename T, typename. . . Types> void print (const T& first. Arg, const Types&. . . args) { std: : cout << first. Arg << std: : endl; // print first argument print(args. . . ); // call print() for the remaining argument }

Summary

Summary

Summary of C++ STL Ø Motivations for using templates, functor adaptors, and lambdas Ø

Summary of C++ STL Ø Motivations for using templates, functor adaptors, and lambdas Ø “Duck Typing” Ø Choosing appropriate STL container type based on how container is used in the program Ø Ø STL Basic Containers STL Algorithms and Iterators Specialize STL algorithms with functions, functors, lambdas, and predefined functor adaptors Function / Class Tempaltes

The End

The End