CNS 3370.  Template Specialization  Member Templates  Template Metaprogramming  Template Idioms  Templates and Friends 2 CNS 3370 - Templates.

Slides:



Advertisements
Similar presentations
Brown Bag #3 Return of the C++. Topics  Common C++ “Gotchas”  Polymorphism  Best Practices  Useful Titbits.
Advertisements

The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
C++ Basics Variables, Identifiers, Assignments, Input/Output.
Exceptions, Templates, And The Standard Template Library (STL) Chapter 16.
C++ How to Program, 7/e © by Pearson Education, Inc. All Rights Reserved.
Chapter 14: Overloading and Templates
Chapter 16 Templates. Copyright © 2006 Pearson Addison-Wesley. All rights reserved Learning Objectives  Function Templates  Syntax, defining 
 2003 Prentice Hall, Inc. All rights reserved. 1 Chapter 11 - Templates Outline 11.1 Introduction 11.2 Function Templates 11.3 Overloading Function Templates.
Templates. Class templates – why? Writing programs we often use abstract data types such as stack, queue or tree. Implementations of these types may be.
 2006 Pearson Education, Inc. All rights reserved. Templates (again)CS-2303, C-Term Templates (again) CS-2303 System Programming Concepts (Slides.
Templates. Objectives At the conclusion of this lesson, students should be able to Explain how function templates are used Correctly create a function.
CSE 332: C++ Classes From Procedural to Object-oriented Programming Procedural programming –Functions have been the main focus so far Function parameters.
1 CSC241: Object Oriented Programming Lecture No 07.
Review of C++ Programming Part II Sheng-Fang Huang.
Computer Science and Software Engineering University of Wisconsin - Platteville 7. Inheritance and Polymorphism Yan Shi CS/SE 2630 Lecture Notes.
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
CSE 332: C++ Algorithms II From Last Time: Search with Generic Iterators Third generalization: separate iterator type parameter We arrive at the find algorithm.
LECTURE LECTURE 17 More on Templates 20 An abstract recipe for producing concrete code.
COMPUTER PROGRAMMING. Data Types “Hello world” program Does it do a useful work? Writing several lines of code. Compiling the program. Executing the program.
CSE 332: C++ templates This Week C++ Templates –Another form of polymorphism (interface based) –Let you plug different types into reusable code Assigned.
Templates Zhen Jiang West Chester University
C++ How to Program, 8/e © by Pearson Education, Inc. All Rights Reserved. Note: C How to Program, Chapter 22 is a copy of C++ How to Program Chapter.
 2003 Prentice Hall, Inc. All rights reserved. 1 Chapter 11 - Templates Outline 11.1 Introduction 11.2 Function Templates 11.3 Overloading Function Templates.
The Rest of the Story.  Constructors  Compiler-generated  The Initializer List  Copy Constructors  Single-arg (conversion ctors)  The Assignment.
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style ADVANCED PROGRAM DESIGN WITH C++ Templates.
CSE 332: C++ Type Programming: Associated Types, Typedefs and Traits A General Look at Type Programming in C++ Associated types (the idea) –Let you associate.
Introduction to Classes in C++
Operator Overloading & Exception Handling TCP1201 OOPDS 1 Lecture 5 1.
CNS  Executive Overview  Template Parameters  Function Template Issues 2 CNS Templates.
Understanding C++ Templates CNS 3370 Copyright 2006, Fresh Sources, Inc.
Templates An introduction. Simple Template Functions template T max(T x, T y) { if (x > y) { return x; } else { return y; } } int main(void) { int x =
Programming Languages by Ravi Sethi Chapter 6: Groupings of Data and Operations.
Copyright © Curt Hill Generic Classes Template Classes or Container Classes.
1 Inheritance. 2 Why use inheritance?  The most important aspect of inheritance is that it expresses a relationship between the new class and the base.
©Fraser Hutchinson & Cliff Green C++ Certificate Program C++ Intermediate Operator Overloading.
C# Classes and Inheritance CNS 3260 C#.NET Software Development.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Templates.
C++ How to Program, 9/e © by Pearson Education, Inc. All Rights Reserved.
Operator Overloading. Binary operators Unary operators Conversion Operators –Proxy Classes bitset example Special operators –Indexing –Pre-post increment/decrement.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 15: Overloading and Templates.
CSC 143F 1 CSC 143 Constructors Revisited. CSC 143F 2 Constructors In C++, the constructor is a special function automatically called when a class instance.
1 Becoming More Effective with C++ … Day Two Stanley B. Lippman
Template Lecture 11 Course Name: High Level Programming Language Year : 2010.
1 CISC181 Introduction to Computer Science Dr. McCoy Lecture 26 Clicker Questions December 3, 2009.
Chapter 16 Templates Copyright © 2008 Pearson Addison-Wesley. All rights reserved.
CSE 332: C++ templates and generic programming II Review: Concepts and Models Templates impose requirements on type parameters –Types that are plugged.
 Binary operators  Unary operators  Conversion Operators  Proxy Classes (simulating a reference) ▪ bitset example  Special operators  Indexing 
CS 342: C++ Overloading Copyright © 2004 Dept. of Computer Science and Engineering, Washington University Overview of C++ Overloading Overloading occurs.
 2006 Pearson Education, Inc. All rights reserved Templates.
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
MAITRAYEE MUKERJI Object Oriented Programming in C++
CSE 332: C++ Exceptions Motivation for C++ Exceptions Void Number:: operator/= (const double denom) { if (denom == 0.0) { // what to do here? } m_value.
Chapter 2 Objects and Classes
Operator Overloading CS 3370 – C++ Chapter 14.
Operator Overloading Introduction
Yan Shi CS/SE 2630 Lecture Notes
Programming with ANSI C ++
C++ Templates.
Templates.
7. Inheritance and Polymorphism
Chapter 14 Templates C++ How to Program, 8/e
Chapter 11 - Templates Outline Introduction Function Templates Overloading Function Templates Class Templates Class.
Abstraction: Generic Programming, pt. 2
Chapter 11 - Templates Outline Introduction Function Templates Overloading Function Templates Class Templates Class.
Overview of C++ Polymorphism
Lab4 problems More about templates Some STL
CS410 – Software Engineering Lecture #5: C++ Basics III
Chapter 11 - Templates Outline Introduction Function Templates Overloading Function Templates Class Templates Class.
Chapter 11 - Templates Outline Introduction Function Templates Overloading Function Templates Class Templates Class.
四時讀書樂 (春) ~ 翁森 山光照檻水繞廊,舞雩歸詠春風香。 好鳥枝頭亦朋友,落花水面皆文章。 蹉跎莫遣韶光老,人生唯有讀書好。
Presentation transcript:

CNS 3370

 Template Specialization  Member Templates  Template Metaprogramming  Template Idioms  Templates and Friends 2 CNS Templates

 A template by nature is a generalization  It becomes specialized for a particular use when the actual template arguments are provided  A particular instantiation is therefore a specialization  But there is another type of “specialization”… 3 CNS Templates

 You may need special “one-off” behavior for certain template arguments  Common case: T = char*  You can provide custom code for each case  both full or partial specializations for class templates  the compiler will use your explicit versions instead of generating code from the primary template 4 CNS Templates

 Allowed, but not needed because you can always just provide a plain overloaded function to do the job  Exception: useful for when you only want to specialize a subset of the member functions of a class 5 CNS Templates

// A Primary Template template class Foo { public: void f(); void g(); }; template void Foo ::f() { cout << "f using primary template\n"; } template void Foo ::g() { cout << "g using primary template\n"; } 6 CNS Templates

// The Full Specialization template<> class Foo { public: void f(); void g(); }; // NOTE: No template keyword here // Also: These go in a.cpp void Foo ::f() { cout << "f using int specialization\n"; } void Foo ::g() { cout << "g using int specialization\n"; } 7 CNS Templates

int main() { Foo c; Foo i; c.f(); c.g(); i.f(); i.g(); } /* Output: f using primary template g using primary template f using int specialization g using int specialization */ 8 CNS Templates

 You may specialize only selected member functions, if desired  The other member functions will come from the primary template  All types of members can be selectively specialized  Static members, Member templates 9 CNS Templates

template<> void Foo ::g() { cout << "g using int specialization\n"; } int main() { Foo c; Foo i; c.f(); c.g(); i.f(); i.g(); } /* Output f using primary template g using primary template f using primary template g using int specialization */ 10 CNS Templates

 Can specialize on a subset of template arguments  Can also specialize on “pointer-ness” or “const- ness” of arguments  vector is actually a partial specialization:  It leaves the allocator type “open”: template class vector {…}; 11 CNS Templates

template class C { public: void f() { cout << "Primary Template\n"; } }; template class C { public: void f() { cout << "T == int\n"; } }; template class C { public: void f() { cout << "U == double\n"; } }; template class C { public: void f() { cout << "T* used\n"; } }; template class C { public: void f() { cout << "U* used\n"; } }; 12 CNS Templates

template class C { public: void f() { cout << "T* and U* used\n"; } }; template class C { public: void f() { cout << "T == U\n"; } }; int main() { C ().f(); // 1: Primary template C ().f(); // 2: T == int C ().f(); // 3: U == double C ().f(); // 4: T == U C ().f(); // 5: T* used [T is float] C ().f(); // 6: U* used [U is float] C ().f(); // 7: T* and U* used [float, int] // The following are ambiguous: // 8: C ().f(); // 9: C ().f(); // 10: C ().f(); // 11: C ().f(); // 12: C ().f(); } 13 CNS Templates

 You must provide all functions you want clients to have when specializing a class  An alternative is to only specialize selected member functions, leaving the rest to the primary template  You can do full or partial specializations of class templates  You can’t partially specialize function templates  And you shouldn’t fully specialize function templates ▪ Except as described above for member functions 14 CNS Templates

15  Some things cannot be resolved when the compiler first encounters a template definition  Anything dependent on a template parameter  The compiler must wait until instantiation time to resolve those issues  When the actual template arguments are known  Hence, a 2-step template compilation process:  1) Template Definition  2) Template Instantiation

CNS Templates 16  Template definition time  The template code is parsed  Obvious syntax errors are caught  Non-dependent names are looked up in the context of the template definition (no waiting needed)  Template instantiation time  Dependent names are resolved  Which specialization to use is determined  Examples follow…

CNS Templates 17 void f(double) { cout << "f(double)" << endl; } template class X { public: void g() { f(1); } }; void f(int) { cout << "f(int)" << endl; } int main() { X ().g(); }

 Non-dependent names are not looked up in base classes  Because a specialization found later may apply  If a class template has a dependent base class, you want calls looked up in Phase 2  When specializations are resolved  Calls to such functions must be qualified  This makes the name dependent  Otherwise they’ll be looked up in Phase 1 and will fail  See next slide… 18 CNS Templates

19 template class PQV : protected vector { Compare comp; public: PQV(Compare cmp = Compare()) : comp(cmp) { make_heap(begin(),end(), comp); } const T& top() const { return front(); } void push(const T& x) { push_back(x); push_heap(begin(), end(), comp); } void pop() { pop_heap(begin(), end(), comp); pop_back(); } };

CNS Templates 20 template class PQV : protected vector { Compare comp; public: PQV(Compare cmp = Compare()) : comp(cmp) { make_heap(this->begin(),this->end(), comp); } const T& top() const { return this->front(); } void push(const T& x) { this->push_back(x); push_heap(this->begin(),this->end(), comp); } void pop() { pop_heap(this->begin(),this->end(), comp); this->pop_back(); } };

CNS Templates 21  When necessary, clue the compiler as to which names are dependent by qualifying them  They’ll get looked up in Phase 2  Remember:  Non-dependent names are looked up immediately  But not in dependent base classes ▪ “x” is not always the same as “this->x”!

 Variables  Data members; either static or non-static  Functions  Member functions, either static and non-static  Types  Either nested classes or typedefs  Templates  “Member Templates”  Use independent template parameters 22 CNS Templates

template class vector { public: class MyIteratorType {…}; typedef MyIteratorType iterator; … }; Can say: vector ::iterator p = v.begin(); 23 CNS Templates

 Can use typename instead of class in a template parameter declaration  Some people use class when the expected argument(s) must not be built-in types  And they use typename when “anything goes”  Just a style issue 24 CNS Templates

 Consider the expression T::X  When inside a template with type parameter T  The compiler assumes X refers to a static member (the parser has to assume something, since T is unknown at first)  Note: X is a dependent name  If X is a type, instead, use the typename keyword to inform the compiler… 25 CNS Templates

// A Print function for standard sequences template > class Seq> void printSeq(Seq & seq) { for(typename Seq ::iterator b = seq.begin(); b != seq.end();) cout << *b++ << endl; } int main() { // Process a vector vector v; v.push_back(1); v.push_back(2); printSeq(v); // Process a list list lst; lst.push_back(3); lst.push_back(4); printSeq(lst); } 26 CNS Templates

 Infers the type of a variable from its initializer  very handy!!! for(auto b = seq.begin(); b != seq.end();) cout << *b++ << endl; CNS Templates 27

 Can also nest template definitions inside a class  Very handy for conversion constructors:  template class complex { public: template complex(const complex &);  Inside of STL sequences: template deque(InputIterator first, InputIterator last, const Allocator& = Allocator());  Example on next slide

template class Outer { public: template class Inner { public: void f(); }; template template void Outer ::Inner ::f() { cout << "Outer == " << typeid(T).name() << endl; cout << "Inner == " << typeid(R).name() << endl; cout << "Full Inner == " << typeid(*this).name() << endl; } int main() { Outer ::Inner inner; inner.f(); }

Outer == int Inner == bool Full Inner == Outer ::Inner

 Example: std::bitset::to_s tring  template basic_string to_string() const;  Because strings are themselves templates! ▪ char vs. wchar_t  So you must explicitly specialize a call to bitset::to_string( ) to indicate the return type  But compilers assume member functions are not templates!  You need to give the compiler a clue about the ‘<‘

 There are contexts in which a ‘<‘ will be interpreted as a less-than operation, instead of the beginning of a template argument list  When using member function templates, for example  The template keyword tells the compiler to assume that a template is being used instead of a less-than operation  Example on next slide:  Converts a bitset to a string (but needs to know the char type)  bitset::to_string( ) needs a template context: string s = bs.to_string, // error allocator >();

template basic_string bitsetToString(const bitset & bs) { return bs.template to_string, allocator >(); } int main() { bitset bs; bs.set(1); bs.set(5); cout << bs << endl; // string s = bitsetToString (bs); cout << s << endl; // }

 Compile-time Computation!  whoa!  Has been proven to be “Turing complete”  means that theoretically, you can do anything at compile time  in practice, it’s used for custom code generation, compile-time assertions, and numerical libraries  See next slide and Hanoi.cpp 34 CNS Templates

template struct binary { enum {value = binary ::value << 1 | N%10}; }; // A (full) specialization to stop the recursion. template<> struct binary { enum {value = 0}; }; int main() { cout ::value << endl; // 5 cout ::value << endl; // 622 cout ::value << endl; // 231 } 35 CNS Templates

 Traits  A Curiously Recurring Template Pattern CNS Templates 36

 A way to store type-specific code for templates  “Compile-time polymorphism”  Use separate template specializations for each type  Examples:  std::numeric_limits 37 CNS Templates

template class numeric_limits { public: static const bool is_specialized = false; static T min() throw(); // for float, etc. static T max() throw(); static const int digits = 0; static const int digits10 = 0; static const bool is_signed = false; static const bool is_integer = false; static const bool is_exact = false; static const int radix = 0; static T epsilon() throw(); CNS Templates

 Can use a static data member that tracks the object count  Constructors increment  Destructors decrement 39 CNS Templates

// This is C++ 101: class CountedClass { static int count; public: CountedClass() { ++count; } CountedClass(const CountedClass&) { ++count; } ~CountedClass() { --count; } static int getCount() { return count; } }; int CountedClass::count = 0; 40 CNS Templates

 The logic for counting objects is type- independent  It would be a shame to replicate that code for each class to be counted  The non-template solution for code sharing is usually inheritance  See next slide… 41 CNS Templates

class Counted { static int count; public: Counted() { ++count; } Counted(const Counted&) { ++count; } ~Counted() { --count; } static int getCount() { return count; } }; int Counted::count = 0; // All derived classes share the same count! class CountedClass : public Counted {}; class CountedClass2 : public Counted {}; 42 CNS Templates

 We need a separate count for each class to be counted  So we need to inherit from a different class for each client class  Hence, we need to use both inheritance (OOP/dynamic polymorphism) and templates (compile-time polymorphism)  See next slide… 43 CNS Templates

template class Counted { static int count; public: Counted() { ++count; } Counted(const Counted &) { ++count; } virtual ~Counted() { --count; } static int getCount() { return count; } }; template int Counted ::count = 0; // Curious class definitions!!! class CountedClass : public Counted {}; class CountedClass2 : public Counted {}; 44 CNS Templates

 A class, T, inherits from a template that specializes on T!  class T : public X {…};  Only valid if X is not dependent on the (non- static) implementation of T  i.e., during Phase 1 45 CNS Templates

 Inherit Singleton-ness  Uses Meyers’ static singleton object approach  Since nothing non-static is inherited, the size is known at template definition time  Protected constructor, destructor  Disables copy/assign  See next slide… 46 CNS Templates

// Base class – encapsulates singleton-ness template class Singleton { Singleton(const Singleton&); Singleton& operator=(const Singleton&); protected: Singleton() {} virtual ~Singleton() {} public: static T& instance() { static T theInstance; // Meyers' Singleton return theInstance; } }; 47 CNS Templates

// A sample class to be made into a Singleton class MyClass : public Singleton { int x; protected: friend class Singleton ; // to create it MyClass() { x = 0; } public: void setValue(int n) { x = n; } int getValue() const { return x; } }; int main() { MyClass& m = MyClass::instance(); cout << m.getValue() << endl; m.setValue(1); cout << m.getValue() << endl; } 48 CNS Templates

49

 How can we add a stream inserter?  ostream& operator &); template class Box { T t; public: Box(const T& theT) : t(theT) {} }; 50 CNS Templates

template class Box { T value; public: Box(const T& t) { value = t; } friend ostream& operator &); }; template ostream& operator b) { return os << b.value; } 51 CNS Templates

 The inserter is not a template  Because it’s not a member function  But it uses a template parameter (T)!  What do we want?  Our operator<<( ) should be a template  And we want a distinct specialization for each T  But it can’t be a member template! ▪ That would introduce an independent template parm  Aargh! 52 CNS Templates

 There are special rules for friend function templates to class templates  Use angle brackets in the declaration of the friend  But the friend must have been previously declared  This also requires a forward declaration of Box  See Next Slide 53 CNS Templates

// Forward declarations template class Box; template ostream& operator<<(ostream&, const Box &); template class Box { T value; public: Box(const T& t) { value = t; } friend ostream& operator (ostream&, const Box &); }; template ostream& operator & b) { return os << b.value; } 54 CNS Templates

 Define body of op<< in situ (i.e.,inside of Box)  Such an op<< is not a template!  No angle brackets are used  A new ordinary function is created for each specialization of Box!  See next slide 55 CNS Templates

template class Box { T value; public: Box(const T& t) { value = t; } friend ostream& operator & b) { return os << b.value; } }; 56 CNS Templates