Introduction to C Programming Module 4 Function and


























- Slides: 26
Introduction to C++ Programming Module 4 Function and Class Templates Yaodong Bi, Ph. D. Department of Computing Sciences University of Scranton (717)941 -6108 bi@cs. uofs. edu August 20, 1998 bi@cs. uofs. edu
Outline z Module 1 - An Overview of C++ and OO Programming z Module 2 - Classes and Operator Overloading z Module 3 - Inheritance and Dynamic Binding z Module 4 - Function and Class Templates z Module 5 - C++ Stream I/O and Exception Handling August 20, 1998 bi@cs. uofs. edu 2
Review of Module 3 z Public Inheritance and Protected Members z Constructors and destructors in derived classes z Redefine Base-class Members in Derived Classes z Type Conversions z Polymorphism and Virtual Functions z Virtual Destructors z Abstract Classes and Concrete classes z Multiple Inheritance z Virtual Base Classes August 20, 1998 bi@cs. uofs. edu 3
Outline of Module 4 z Function Templates y. Function Template Definition y. Function Template Instantiation y. Template Explicit Specialization y. Overloading Function Templates y. Template Compilation Models z Class Templates y. Class Template Definition y. Class Template Instantiation y. Members of Class Templates y. Friend Declarations in Class Templates y. Class Template Compilation Model August 20, 1998 bi@cs. uofs. edu 4
Example 1: Templates // stack. Tmpl. h const int max. Size = 10; template <class T> class CStack { public: // public interface CStack(int sz = max. Size); void Push (const T& item); T Pop(); bool Is. Empty() const; bool Is. Full() const; ~CStack(); private: // private implementation T* m_Array; int m_n. Top; int m_n. Size; }; August 20, 1998 // stack. cpp #include <iostream. h> #include "stack. Tmpl. h" template<class T> CStack<T>: : CStack(int sz) { m_Array = new T[sz]; m_n. Size = sz; m_n. Top = -1; }; template<class T> void CStack<T>: : Push(const T& item) { m_Array[++m_n. Top] = item; }; template<class T> T CStack<T>: : Pop() { return m_Array[m_n. Top--]; }; bi@cs. uofs. edu 5
Example 1: Templates - cont’d // stack. cpp - cont’d // template. cpp template<class T> bool CStack<T>: : Is. Empty() const { return (m_n. Top < 0); }; template<class T> bool CStack<T>: : Is. Full() const { return (m_n. Top == m_n. Size - 1); }; template<class T> CStack<T>: : ~CStack() { delete [] m_Array; }; #include <iostream. h> #include "stack. Tmpl. cpp” August 20, 1998 // function template<class T> void Print(CStack<T>& stack) { while (!stack. Is. Empty()) { cout << stack. Pop() << endl; } } bi@cs. uofs. edu 6
Example 1: Templates - cont’d // template. cpp z Template Function #include <iostream. h> #include "stack. Tmpl. cpp" template<class T> void Print(CStack<T>& stack) {…} template <class T> void Print(CStack<T>& stack); z Template Class void main() { CStack<int> istack; CStack<char> cstack; z Class Template Instantiation template <class T> class CStack { … }; for ( char i = 'A'; i < 'A'+10; i++) { if (!istack. Is. Full()) istack. Push(int(i)); if (!cstack. Is. Full()) cstack. Push(i); } Print(istack); Print(cstack); CStack<int> istack; CStack<char> cstack; …. if (!istack. Is. Full()) istack. Push(int(i)); if (!cstack. Is. Full()) cstack. Push(i); z Function Template Instantiation Print(istack); Print(cstack); } August 20, 1998 bi@cs. uofs. edu 7
Function Template Definition z Syntax template <parameter_list> ret_type func_name(fun_parameters) ex: template <class T, int sz> T min(T (&arr)[sz]); template <class T> void print(CStack<T>& stack) {} z Template parameters y template type parameters x. Representing a type x. Syntax: class type_name or typename type_name. ex: class T x. Each type parameter must be preceded by class or typename. Ex: tempate<class T 1, T 2, int sz> T 1 foo() {} // T 2 needs class y template nontype parameters x. Representing a constant expression x. The value must be known at compile-time x. Declared as a ordinary variable ex: int sz August 20, 1998 bi@cs. uofs. edu 8
Function Template Definition z Parameter names y The name of a template parameter can be treated as a locallydefined type/variable after it is declared. template <class T, T const_value, int sz> void foo(const T&). // The type parameter T is used in the parameter list template < T const_value, class T, int sz> void foo(const T&). // error: the first appearance of T is not declared yet y When a global object, function, or type uses the same name as a template parameter, the global scope name is hidden. typedef double Type; template <class Type> Type min(Type a, Type b) { … Type tmp; } // tmp has the type of the template parameter Type y A object or variable in the template function cannot have the same name as that of a template parameter. template <class Type> Type min(Type a, Type b) { … typedef double Type; } // error: re-declare template parameter Type August 20, 1998 bi@cs. uofs. edu 9
Function Template Instantiation z Instantiation y when the template is invoked. template <class T, int sz> T min(T (&arr)[sz]) {/* … */ } template <class T> void print(CStack<T>& stack) {/* … */ } int ia[] = {10, 11, 12, 15}; double da[] = {1. 1, 1. 2, 1. 3}; CStack<int> i. Stack; CStack<CString> s. Stack …. int I = min(ia); // T => int, sz => 4; double d= min(da); // T =>double, sz = 3; print(i. Stack); // T => int print(s. Stack); // T => CString y When the address of the template is taken int (*pf)(int (&)[10]) = &min; // pf points to int min(int (&)[10]) void (*pff)(CStack<int> &) = &print; // pff points to void print(CStack<int>) August 20, 1998 bi@cs. uofs. edu 10
Function Template Instantiation z Template argument deduction y The types and values of the template arguments are determined by an examination of the types of the function arguments. Ex: template <class U, class V> U foo(U, V) {} double d; int i; double d 1=foo(d, i) // instantiate double foo(double, int) y The return type of the instantiation is not considered during template argument deduction. double da[3] = {1. 1, 1. 2, 1. 3}; int i = min(da); // return a double, then convert it to int y If a template parameter occurs multiple times, each deducted type must exactly match the first type deducted. Ex: template <class T> T min(T, T) {} unsigned int ui; min(ui, 1024); // error: cannot instantiate min(unsigned, int); min(ui, unsigned(1024)) // okay: min(unsigned, unsigned); August 20, 1998 bi@cs. uofs. edu 11
Function Template Instantiation z Explicit Template Arguments y Explicitly specify the types of the template arguments ex 1: template <class T> T min(T, T) {} min<unsigned, int> (ui, 1024); // min(unsigned, unsigned) instantiated // the second argument is converted to unsigned. ex 2: template <class T, class U, class V> T foo(U, V) {} // T cannot be deduced from the function arguments int x = foo<int , char, unsigned > (ch, ui); // T is int. y In the explicit specification, we need only list the arguments that cannot be implicitly deduced. We can omit only trailing arguments. int x = foo<int> (ch, ui); // int foo(char, unsigned) int (*pf)(char, int) = &foo<int>; // int foo(char, int) int x = foo<int, , char> (ch, char); // Error: trailing arguments only y When the template arguments are explicitly specified, there is no need to deduce the template arguments. August 20, 1998 bi@cs. uofs. edu 12
Template Explicit Specialization y. When T is const char*, the following template doesn’t work! template<class T> T min(T t 1, T t 2) { return (t 1 > t 2 ? t 1 : t 2} // return the smaller between t 1 and t 2 y. Define an explicitly specialization for const char* typedef const char* PCC; template<> PCC min<PCC> (PCC s 1, PCC s 2) { return (strcmp(s 1, s 2) > 0 ? s 1 : s 2); } y. When min(const char*, const char*) is called, the above specialization will be invoked. For others, the generic template will be instantiated and invoked. int i = min(10, 5); // call to instantiation const char* p =min(“hello”, “world”); // call to explicit specialization y. The specialization list may be omitted if the arguments can be deduced. template<> PCC min (PCC s 1, PCC s 2); //okay y. The declaration of an specialization must be seen before it is used -otherwise, compile-time error. August 20, 1998 bi@cs. uofs. edu 13
Overloading Function Templates y A function template can be overloaded. template <class U> class Array{ /* … */}; template<class T> T min(const Array<T>&, int); template<class T> T min(const T*, int); template<class T> T min(T, T); // #1 // #2 // #3 y The most specialized definition is chosen for an instantiation. Array<int> i. Array(1024); int ia[1024]; … int ret 1 = min(i. Array, 1024); // #1 is most specialized (compared to #3), #2 is not applicable. int ret 1 = min(ia, 1024); // #2 is most specialized, T=>int. In #3, T=>int* int ret 1 = min(1. 23, 2. 34); // #3 is the one applicable. y Overloaded function templates may lead to ambiguities when a template instantiation is invoked. August 20, 1998 bi@cs. uofs. edu 14
Overloading Function Templates y A function template may also have the same name as an ordinary nontemplate function. Ex 1: template <class T> T sum(T, int) {} // function template double sum(double, double) {} // nontemplate function … int i; double d 2 = sum(d, i); // Which one called? // since the template has a perfect match, the template is called. Ex 2: template <class T> T sum(T, T) {} // function template double sum(double, double) {} // nontemplate function … double d 1, d 2; double d 3 = sum(d 1, d 2); // Both have the perfect match. // when a template and an ordinary have the perfect match, // the ordinary nontemplate will be called. y Further reading is needed for this topic. Read Stroustrup’s and Lippman’s books. August 20, 1998 bi@cs. uofs. edu 15
Template Compilation Models y Inclusion compilation model // inclusion. cpp -- contains the template declaration and definition. template <class T> T min(T t 1, T t 2) { return t 1 > t 2 ? t 1 : t 2; } //main. cpp #include “inclusion. cpp” // the template file is included in all the files. double ret = min( 2, 20); y Separation compilation model // separate. h -- contains the template declaration only template <class T> T min(T t 1, T t 2); // separate. cpp --- the template definition #include “inclusion. h” export template <class T> T min(T t 1, T t 2) { return t 1 > t 2 ? t 1 : t 2; } // main. cpp --- the user #include “inclusion. h” // the header file is included in all the files. // only the declaration is included. double ret = min( 2, 20); y MS Visual C++ 5. 0 does not seem to support the separation model August 20, 1998 bi@cs. uofs. edu 16
Class Template Definition z Syntax template <class T> class CStack {… void Push (const T& item); T Pop(); …. T* m_Array; }; z Template parameters y template type parameters x. Representing a type x. Syntax: class type_name or typename type_name. ex: class T x. Each type parameter must be preceded by class or typename. Ex: tempate<class T 1, T 2, int sz> class foo {} // T 2 needs class y template nontype parameters x. Representing a constant expression x. The value must be known at compile-time x. Declared as a ordinary variable ex: int sz y Example: template <class Type, int size> class buffer; August 20, 1998 bi@cs. uofs. edu 17
Class Template Definition z Parameter names y The name of a template parameter can be treated as a locallydefined type/variable after it is declared. template <class T, T const_value, int sz> class foo {. . }; // okay y When a global object, function, or type uses the same name as a template parameter, the global scope name is hidden. typedef double Type; template <class Type> class foo { … Type tmp; } // tmp is of the template parameter Type, not global typedef’ed Type y A object or variable in the template function cannot have the same name as that of a template parameter. template <class Type> class foo { … typedef double Type; } // error: re-declare template parameter Type z Default arguments y Both type and nontype parameters can have default arguments template <class Type, int size = 1024> class foo {. . . }; August 20, 1998 bi@cs. uofs. edu 18
Class Template Instantiation z Instantiation y The name of a class template instantiation must always specify the template arguments explicitly. CStack<int> istack; // istack is a stack of integers CStack<CString> str. Stack; // str. Stack is a stack of CStrings y Objects from instantiations can be used the same way as objects of nontemplate classes. i. Stack. Push(int_item); CString str = str. Stack. Pop(); y A template declaration or definition can refer to a class template or to an instantiation of a class template <class Type> void foo(CStack<Type>, CStack<int>) // generic template // template instantiation y In a nontemplate definition, only class template instantiation can be used. xvoid foo(CStack<int> & istack) {…} //must be instantiated. August 20, 1998 bi@cs. uofs. edu 19
Member Functions of Class Templates z A member function may be defined within the class definition. template <class T> class CStack {… bool Is. Empty() const { return (m_n. Top < 0); }; }; // The member function is defined as a regular nontemplate member. z A member function may be defined outside the class definition. template<class T> bool CStack<T>: : Is. Empty() const { return (m_n. Top < 0); }; // it is necessary to include <parameter_list> in the scope specifier. template<class T> T CStack<T>: : Pop() { return m_Array[m_n. Top--]; }; // T can be used as a regular class (as the return type) in the def. template<class T> CStack<T>: : CStack(int sz) { m_Array = new T[sz]; m_n. Size = sz; m_n. Top = -1; }; z A member function of a class template is not instantiated automatically when the class template is itself instantiated. The member function is instantiated only if it is used by the program. August 20, 1998 bi@cs. uofs. edu 20
Friend Declarations in Class Templates z Three kinds of friend declarations y A nontemplate friend function or friend class Foo { … void bar(); …}; template <class T> class Queue { friend class foobar; // okay, even it has not been declared. friend ostream& operator<<(ostream& const CStack<T>&); friend void Foo: : bar(); }; // Foo must be defined b/c its member is used. y A bound friend class or function template : one-to-one. template <class T> class foobar { … }; template <class T> void foo(Queue<T>); template <class T> class queue. Item { friend class foobar<T>; // okay. friend void foo<T>(Queue<T>); // okay. friend void Foo<T>: : bar(); y An unbound friend class or function template : one-to-many. template <class T> class queue. Item { template <class U> friend class foobar; // all instantiations are friend. template <class U> friend void foo(Queue<U>); }; // all instantiation. August 20, 1998 bi@cs. uofs. edu 21
Template Compilation Models y Inclusion compilation model // inclusion. h -- contains the class def. And member function definition. template <class T> class Foo{… void bar(); …}; template <class T> Foo<T>: : bar() {…} //main. cpp #include “inclusion. h” // the template file is included in all the files. Foo<int> i. Object; y Separation compilation model // separate. h -- contains the template declaration only export template <class T> class Foo {… void bar(); …}; // separate. cpp --- the template definition #include “inclusion. h” export template <class T> Foo<T>: : bar() {…} // main. cpp --- the user #include “inclusion. h” Foo<int> i. Object; // the header file is included in all the files. // only the declaration is included. y MS Visual C++ 5. 0 does not seem to support the separation model August 20, 1998 bi@cs. uofs. edu 22
Summary of Module 4 z Function Templates y. Function Template Definition y. Function Template Instantiation y. Template Explicit Specialization y. Overloading Function Templates y. Template Compilation Models z Class Templates y. Class Template Definition y. Class Template Instantiation y. Members of Class Templates y. Friend Declarations in Class Templates y. Class Template Compilation Model August 20, 1998 bi@cs. uofs. edu 23
Advice z Debug concrete examples before generalizing to a template. z Use templates to express algorithms that apply to many argument types. z Always declare the general form of a template before specialization. z Use specialization and overloading to provide a single interface to implementations of the same concept for different types. z Remember to export template definitions that need to be accessible from other translation units (files). z Use explicit instantiation to minimize compile time and link time. August 20, 1998 bi@cs. uofs. edu 24
Programming Assignments z Improve Example 1: Stack Template y Change the default size of the array to a template parameter. What is the difference from the original implementation? template <class T, int size> class CStack { …. }; y Modify the Push() and Pop functions. template <class T, int size> bool CStack<T, size> : : Push(const T&); template <class T, int size> bool CStack<T, size> : : pop(T&); y Write a template overloading the operator <<. It prints the content of the stack in a bottom-up fashion. template <class T, int size> ostream& operator<<(ostream&, const CStack<T, size>&); y Write a main() to test your new template. z Design a string template y Design a concrete class for strings of characters, debug the class. y Convert the class into a template. y Overload I/O operators for the template. y Write a main() to test your new template. August 20, 1998 bi@cs. uofs. edu 25
August 20, 1998 bi@cs. uofs. edu 26