Presentation is loading. Please wait.

Presentation is loading. Please wait.

C++ Template.

Similar presentations


Presentation on theme: "C++ Template."— Presentation transcript:

1 C++ Template

2 Introduction A general definition of functions and classes
Further simplifies the previous function overloading Another form of polymorphism In a template, the data type is the parameter! The precise definitions of the template functions and classes are determined in run-time based on the data type!

3 Function Templates Consider the following function
int max (int x, int y) { return (x > y? x : y); } It only works for the int type of variables! How can we make it work for other types of variables?

4 Function Templates Use function overloading!
float max (float x, float y) { return (x > y? x : y); } double max (double x, double y) { return (x > y? x : y); } char max (char x, char y) { return (x > y? x : y); } ……

5 Function Templates Do we have a smarter way to do that?
Use function overloading! float max (float x, float y) { return (x > y? x : y); } Do we have a smarter way to do that? double max (double x, double y) { return (x > y? x : y); } char max (char x, char y) { return (x > y? x : y); } ……

6 Function Templates! First line called "template prefix"
template <class T> T max (T x, T y) { return (x > y? x : y); } Type parameter First line called "template prefix" Tells compiler what’s coming is "template" And that T is a type parameter

7 Function Templates! First line called "template prefix"
template <class T> T max (T x, T y) { return (x > y? x : y); } First line called "template prefix" Tells compiler what’s coming is "template" And that T is a type parameter In template <class T>, "class" means "type", or "classification“! It is NOT the class we learned before!

8 Function Templates! First line called "template prefix"
template <class T> T max (T x, T y) { return (x > y? x : y); } First line called "template prefix" Tells compiler what’s coming is "template" And that T is a type parameter In template <class T>, "class" means "type", or "classification“! It is NOT the class we learned before! To avoid confusion, one can use “typename”.

9 Function Templates! T can be replaced by any type in the run time
template <class T> T max (T x, T y) { return (x > y? x : y); } T can be replaced by any type in the run time Predefined or user-defined (like a C++ class type) In function definition body: T used like any other type, just like it has been defined already Note: one can use other symbol than "T", but T is the "traditional" usage

10 How Does this Work? Consider the following example
#include <iostream> using namespace std; template<typename T> T abs(T x) { return x < 0? -x : x; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; return 0; Output is 5 5.5

11 How Does this Work? Consider the following example
#include <iostream> using namespace std; template<typename T> T abs(T x) { return x < 0? -x : x; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; return 0; If not using template, at least two abs functions need to be defined: One for int type, the other for double type Output is 5 5.5

12 How Does this Work? Consider the following example
#include <iostream> using namespace std; template<typename T> T abs(T x) { return x < 0? -x : x; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; return 0; In run-time, compiler determines the actual type for T based on the type of the input variable

13 How Does this Work? Consider the following example
#include <iostream> using namespace std; template<typename T> T abs(T x) { return x < 0? -x : x; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; return 0; In run-time, compiler determines the actual type for T based on the type of the input variable For instance, abs(n), n is int type

14 How Does this Work? Consider the following example
#include <iostream> using namespace std; template<typename T> T abs(T x) { return x < 0? -x : x; } int main() { int n = -5; double d = -5.5; cout << abs(n) << endl; cout << abs(d) << endl; return 0; In run-time, compiler determines the actual type for T based on the type of the input variable For instance, abs(n), n is int type The compiler then creates the following function based on the template int abs(int x) { return x < 0? -x : x; }

15 Difference Between Template Functions and Normal Functions
Compiler won’t generate instance for template functions during compiling. It generates when it is called (see abs example). If a template function is used by several other places in different .cpp files, the template function and its body need to be put in the .h file not only the declaration. The function pointer can only point to instance of the template function.

16 Back to the max function
We now can use template to address our issue with the max function! #include <iostream> using namespace std; template<class T> T max(T x, T y) { return x > y? x : y; } void main() { int n1 = -5, n2 = 0; double d1 = -5.5, d2 = -5.9; cout << max(n1, n2) << endl; cout << max(d1, d2) << endl;

17 Swap values example #include <iostream> using namespace std;
template<class T> T swapVals(T &x, T &y) { T tmp = x; x = y; y = tmp; } class ABC{ public: ABC(float inx=0, float iny=0) {x=inx; y=iny;} private: float x, y; }; void main() { int n1 = -5, n2 = 0; double d1 = -5.5, d2 = -5.9; ABC obj1(3, 4.4),obj2(3.1, 0.2); swapVals(n1, n2); swapVals(d1, d2); swapVals(obj1, obj2); } We can also use it to swap the values of two objects!!!

18 What is the problem of the following example?
// declare template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3); …… // define the template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3) { cout << stuff1 << endl << stuff2 << endl << stuff3 << endl; } class ABC{ public: ABC(float inx=0, float iny=0) {x=inx; y=iny;} private: float x, y; }; void main() { int n1 = -5, n2 = 0.5; double d1 = -5.5, d2 = -5.9; ABC obj1(3, 4.4),obj2(3.1, 0.2); showStuff(1, n1, n2); showStuff(2, d1, d2); showStuff(3, obj1, obj2); }

19 What is the problem of the following example?
// declare template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3); …… // define the template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3) { cout << stuff1 << endl << stuff2 << endl << stuff3 << endl; } class ABC{ public: ABC(float inx=0, float iny=0) {x=inx; y=iny;} private: float x, y; }; void main() { int n1 = -5, n2 = 0.5; double d1 = -5.5, d2 = -5.9; ABC obj1(3, 4.4),obj2(3.1, 0.2); showStuff(1, n1, n2); showStuff(2, d1, d2); showStuff(3, obj1, obj2); } “cout<<“ cannot handle ABC type of objects! Solution?

20 What is the problem of the following example?
// declare template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3); …… // define the template function template<class T> void showStuff(int stuff1, T stuff2, T stuff3) { cout << stuff1 << endl << stuff2 << endl << stuff3 << endl; } class ABC{ public: ABC(float inx=0, float iny=0) {x=inx; y=iny;} friend ostream& operator<<(ostream& os, ABC& obj); private: float x, y; }; void main() { int n1 = -5, n2 = 0.5; double d1 = -5.5, d2 = -5.9; ABC obj1(3, 4.4),obj2(3.1, 0.2); showStuff(1, n1, n2); showStuff(2, d1, d2); showStuff(3, obj1, obj2); } “cout<<“ cannot handle ABC type of objects! Solution? Define an overload operator function! ostream& operator<<(ostream& os, ABC& obj) { os<<“x=“<<x<<“, y=“<<y<<endl; return os; }

21 Multiple Type Parameters
Can have: template<class T1, class T2> Not typical Usually only need one "replaceable" type Cannot have "unused" template parameters Each must be "used" in definition Error otherwise!

22 What is the problem of the following template functions?
template<class T1, class T2> T1 max (T1 num1, T1 num1) { return num1 > num2 ? num1 : num2; } T2 min (T2 num1, T2 num2) return num1 > num2 ? num2 : num1;

23 What is the problem of the following template functions?
template<class T1, class T2> T1 max (T1 num1, T1 num1) { return num1 > num2 ? num1 : num2; } T2 min (T2 num1, T2 num2) return num1 > num2 ? num2 : num1; T2 is not used!

24 What is the problem of the following template functions?
template<class T1, class T2> T1 max (T1 num1, T1 num1) { return num1 > num2 ? num1 : num2; } T2 min (T2 num1, T2 num2) return num1 > num2 ? num2 : num1; T2 is not used! Missing a template prefix!

25 What is the output of the following program?
#include <iostream> using namespace std; template<class T> T max(T x, T y) { return x > y? x : y; } void main() { int n1 = -5, n2 = 0; double d1 = -5.5, d2 = -5.9; cout << max(n1, d2) << endl; cout << max(d1, n2) << endl;

26 What is the output of the following program?
#include <iostream> using namespace std; template<class T> T max(T x, T y) { return x > y? x : y; } void main() { int n1 = -5, n2 = 0; double d1 = -5.5, d2 = -5.9; cout << max(n1, d2) << endl; cout << max(d1, n2) << endl; Compiling error! T ambiguous… How to fix it?

27 Class Templates We can also define template class, which can be considered as the “generalized” classes (i.e., can be used to generate actual classes in run-time). template<class T> class Pair { public: Pair(); Pair(T firstVal, T secondVal); void setFirst(T newVal); void setSecond(T newVal); T getFirst() const; T getSecond() const; private: T first; T second; };

28 Class Templates We can also define template class, which can be considered as the “generalized” classes (i.e., can be used to generate actual classes in run-time). template<class T> class Pair { public: Pair(); Pair(T firstVal, T secondVal); void setFirst(T newVal); void setSecond(T newVal); T getFirst() const; T getSecond() const; private: T first; T second; }; template prefix declaration of the template class

29 Class Templates We can also define template class, which can be considered as the “generalized” classes (i.e., can be used to generate actual classes in run-time). template<class T> Pair<T>::Pair(T firstVal, T secondVal) { first = firstVal; second = secondVal; } template<class T> void Pair<T>::setFirst(T newVal) { first = newVal; } template prefix definition of the member functions of the template class Need to repeat this prefix for each member function Class name before:: is “Pair<T>”!

30 Class Templates How to use the template class? create a class
with T = int Pair<int> score; Pair<char> seats; class Pair { public: Pair(); Pair(int firstVal, int secondVal); void setFirst(int newVal); void setSecond(int newVal); int getFirst() const; int getSecond() const; private: int first; int second; }; create a class with T = char

31 Class Templates Use the template class as the parameter of a function
int addUP(const Pair<int>& the_Pair); create a class with T = int class Pair { public: Pair(); Pair(int firstVal, int secondVal); void setFirst(int newVal); void setSecond(int newVal); int getFirst() const; int getSecond() const; private: int first; int second; }; Overall, template types can be used anywhere standard types can

32 Class Templates We can further define the following function as a template to avoid defining new overload. int addUP(const Pair<int>& the Pair); char addUP(const Pair<char>& the Pair); float addUP(const Pair<float>& the Pair); …… How?

33 Class Templates We can further define the following function as a template to avoid defining new overload. int addUP(const Pair<int>& the_Pair); char addUP(const Pair<char>& the_Pair); float addUP(const Pair<float>& the_Pair); …… template<class T> T addUp(const Pair<T> & the_pair) { return the_pair.first + the_pair.second; }

34 Class Templates We can further define the following function as a template to avoid defining new overload. int addUP(const Pair<int>& the_Pair); char addUP(const Pair<char>& the_Pair); float addUP(const Pair<float>& the_Pair); …… Template<class T> T addUp(const Pair<T> & the_pair) { return the_pair.first + the_pair.second; } Of course, the “+” operator should apply to the summation of T type of objects!

35 Another example What is the problem of this class template? class calc
{ public: int multiply(int x, int y); int add(int x, int y); }; int calc::multiply(int x, int y) { return x*y; } int calc::add(int x, int y) { return x+y; } template<class T> class calc { public: T multiply(T x, T y); T add(T x, T y); }; T calc::multiply(T x, T y) { return x*y; } T calc::add(T x, T y) { return x+y; } What is the problem of this class template?

36 Another example should be What is the problem of this class template?
class calc { public: int multiply(int x, int y); int add(int x, int y); }; int calc::multiply(int x, int y) { return x*y; } int calc::add(int x, int y) { return x+y; } template<class T> class calc { public: T multiply(T x, T y); T add(T x, T y); }; T calc::multiply(T x, T y) { return x*y; } T calc::add(T x, T y) { return x+y; } should be calc<T> What is the problem of this class template?

37 Another example What is the problem of this class template?
template<class T> class calc { public: T multiply(T x, T y); T add(T x, T y); }; T calc<T>::multiply(T x, T y) { return x*y; } T calc<T>::add(T x, T y) { return x+y; } class calc { public: int multiply(int x, int y); int add(int x, int y); }; int calc::multiply(int x, int y) { return x*y; } int calc::add(int x, int y) { return x+y; } What is the problem of this class template?

38 Restrictions on Type Parameter
Only "reasonable" types can be substituted for T Consider: Assignment operator must be "well-behaved" Copy constructor must also work If T involves pointers, then destructor must be suitable! Similar issues as function templates

39 Type Definitions Can define new "class type name"
To represent specialized class template name Example: typedef Pair<int> PairOfInt; Name "PairOfInt" now used to declare objects of type Pair<int>: PairOfInt pair1, pair2; Equivalent to: Pair<int> pair1, pair2; Name can also be used as parameter, or anywhere else type name allowed void fun (PairOfInt &obj);

40 Friends and Templates Friend functions can be used with template classes Same as with ordinary classes Simply requires type parameter where appropriate Very common to have friends of template classes Especially for operator overloads (as we’ve seen)

41 Templates and Inheritance
Nothing new here Derived template classes Can derive from template or non-template class Derived class is then naturally a template class Syntax same as ordinary class derived from ordinary class

42 template <class T>
class Foo { public: Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg) { /* do something for foo */ } T Foo_T; // either a TypeA or a TypeB - TBD foo_arg_t _foo_arg; }; template <class T> class Bar : public Foo<T> { public: Bar (const foo_arg_t bar_arg, const a_arg_t a_arg) : Foo<T>(bar_arg) // base-class initializer Foo<T>::Foo_T = T(a_arg); } Bar (const foo_arg_t bar_arg, const b_arg_t b_arg) : Foo<T>(bar_arg) Foo<T>::Foo_T = T(b_arg); void BarFunc (); };

43 Summary Function templates Class templates
Define functions with parameter for a type Class templates Define class with parameter for subparts of class Predefined vector and basic_string classes are template classes Can define template class derived from a template base class

44 More Compiler Complications
Check your compiler’s specific requirements Some need to set special options Some require special order of arrangement of template definitions vs. other file items Most usable template program layout: Template definition in same file it’s used Ensure template definition precedes all uses Can #include it


Download ppt "C++ Template."

Similar presentations


Ads by Google