Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 25

Class Templates

++C
Class templates – motivation:
class intClass {
int _member;
public:
void print() const;
};

class floatClass {
float _member;
public:
void print() const;
};

2
++C
Class templates

template <class T>


class genericClass {
T _member;
public:
void print() const;
};

3
++C
Class templates
The code is similar to template functions:
• Add template<…> statement before the class
definition
• Use template argument as type in class definition
• To implement methods outside the class definition:
template <class T>
void genericClass<T>::print() const
{
  std::cout << _member;
}
4
++C
Class template instantiation
(only explicit)

int main() {
genericClass<int> intObj;
genericClass<float> floatObj;
...
}

5
What is printed? ++C

template <class T> int main() {


class Test { Test<int> a;
private: Test<int> b;
T val; Test<double> c;
public: cout << Test<int>::count
static int count; << " "
Test() { count++; } << Test<double>::count;
}; return 0;
}
template<class T>
A. 0 0
int Test<T>::count = 0; B. 1 1
C. 2 1
D. 1 0 -
A B C D
vote at clab2020.participoll.com
6
More about template arguments

The following is demonstrated for class templates,


but works for template functions as well

7
++C
Templates with several arguments
template <class T1, class T2>
class A
{
   T1 _d;
   T2 _c;
};
int main()
{
   A<double, int> a;
}
8
++C
Templates with several arguments
template <class T, class U>
void f(T x, U y) {
cout << x << “, ” << y << endl;
};
int main()
{
f( 90 , 1.4);
f<int, short>( 90 , 1.4 );
f<char>( 90 , 1.4 );
}
9
++C
Templates with several arguments
template <class T, class U>
void f(T x, U y) {
cout << x << “, ” << y << endl;
};
int main()
{
f( 90 , 1.4); 90, 1.4
f<int, short>( 90 , 1.4 ); 90, 1
f<char>( 90 , 1.4 ); Z, 1.4
}
10
++C
Are template type parameters enough?
class Buffer
{
   int m_values[10];
};

class Buffer
{
   int m_values[20];
};

The above classes are of different types,


!but no “T” will capture their difference
11
++C
Non-type template parameters
template<class T, int Size>
class Buffer
{
   T m_values[Size];
};

Buffer<char,1024> buff2;
Buffer<int, 256> buff3;

Those are values,


not types
12
++C
Default values for template arguments
template<class T = char, int Size = 1024>
class Buffer
{ C++11

   T m_values[Size];
};

Buffer<char> buff1;
Buffer<> buff2; // same as Buff1, needs <>
Buffer<int, 256> buff3;

13
++C
Template and Types
• Buffer is not a type

• Buffer<char,1024> is a type

• Buffer<>, Buffer<char>,
Buffer<char,1024> are three names for the
same type

• Buffer<char,256> is a different type

14
Templates specialization

Relevant for template classes


++C
Template specialization motivation
template <class Type>
class A int main()
{
{
public:
   Type _data;    A<int> ai(5);
   A(Type data) : _data(data) { }    ai.isBigger(7);
   bool isBigger(Type data); // false
};
A<char*> as("hi");
template <class Type> as.isBigger("bye");
bool A<Type>::isBigger(Type data)
{
   return data > _data; // ?
} }

17
++C
Class template specialization
template <class Type>
class A { ... }; int main()
{
template<>
class A<char*>    A<int> ai(5);
{    ai.isBigger(7);
public: //generic isBigger()
   char* _data;
   A(char* data) : _data(data) { }
A<char*> as("hi");
   bool isBigger(char* data);
}; as.isBigger("bye");

bool A<char*>::isBigger(char *data) //specific isBigger()


{
   return strcmp(data, _data) > 0; }
}

18
++C
Specialization of a single method
template <class Type>
class A int main()
{
{
public:
   Type _data;    A<int> ai(5);
   A(Type data) : _data(data) { }    ai.isBigger(7);
   bool isBigger(Type data); //generic isBigger()
};
template <class Type> A<char*> as("hi");
bool A<Type>::isBigger(Type data) as.isBigger("bye");
{
   return data > _data; //specific isBigger()
} }
template <>
bool A<char*>::isBigger(char *data)
{
   return strcmp(data, _data) > 0;
}
19
++C
Template partial specialization
template <typename T1, typename T2>
class MyClass {
...
};
// partial specialization: same types parameters
template <typename T>
class MyClass<T,T> {
...
};
// partial specialization: second type is int
template <typename T>
class MyClass<T,int> {
...
};
// partial specialization: parameters are pointers
template <typename T1, typename T2>
class MyClass<T1*,T2*> {
...
20 };
++C
Template partial specialization

MyClass<int,float> a; //uses MyClass<T1,T2>


MyClass<float,float> b;//uses MyClass<T,T>
MyClass<float,int> c; //uses MyClass<T,int>
MyClass<int*,float*> d;//uses MyClass<T1*,T2*>

21
Generic stack, generic sort,
code reuse
A few examples of using templates for
generic programming

22
++C
String Stack
class StrStk {
public:
  StrStk(): _first(nullptr) { };
  ~StrStk() { while (!isEmpty()) pop(); }
  void push (string const& s )  { _first = new Node(s, _first); }
  bool isEmpty() const { return _first == nullptr;}
  const string& top () const { return _first->_value; }
  void pop () { Node *n = _first; _first = _first->_next; delete n; }

private:
  StrStk(StrStk const& rhs); // disallow copy from outside
StrStk& operator=(StrStk const& rhs);
  struct Node {
    string _value;
    Node* _next;
    Node(string const& v, Node* n) : _value(v), _next(n) { }
  };
23  Node* _first;
++C
Int Stack
class IntStk {
public:
  IntStk(): _first(nullptr) { };
  ~IntStk() { while (!isEmpty()) pop(); }
  void push (int const& s )  { _first = new Node(s, _first); }
  bool isEmpty() const { return _first == nullptr;}
  const int& top () const { return _first->_value; }
  void pop () { Node *n = _first; _first = _first->_next; delete n; }

private:
  IntStk(IntStk const& rhs); // disallow copy from outside
IntStk& operator=(IntStk const& rhs);
  struct Node {
    int _value;
    Node* _next;
    Node(int const& v, Node* n) : _value(v), _next(n) { }
  };
24  Node* _first;
++C
Generic Classes

• The actual code for maintaining the stack has


nothing to do with the particulars of the
string/int types.
• Now we know that we can have a generic
implementation of stack! …using templates.
• The only thing we need to care for are
assumptions about our Type
 Now think! Which assumptions do we
need T to hold in the general stack?
25
Generic Stack ++C

template <class T> class Stk {


public:
  Stk(): _first(nullptr) { };
  ~Stk() { while (!isEmpty()) pop(); }
  void push (T const& s )  { _first = new Node(s, _first); }
  bool isEmpty() const { return _first == nullptr;}
  const T& top () const { return _first->_value; }
  void pop () { Node *n = _first; _first = _first->_next; delete n; }

private:
  Stk(Stk const& rhs); // disallow copy from outside
Stk& operator=(Stk const& rhs);
  struct Node {
    T _value;
    Node* _next;
    Node(T const& v, Node* n) : _value(v), _next(n) { }
  };
  Node* _first;
26};

You might also like