Lab 18: Templates and Classes

Templates and Classes

Templates in C++ provide a way to write flexible, reusable code for multiple data types without having to rewrite similar logic for each type. This capability is particularly useful for:

§1 Function Templates #

Function templates allow you to write a single function that can work with different data types. Instead of writing separate functions for int, double, float, etc., you can create one template function that handles them all.

Syntax:

template <typename T>
T functionName(T parameter1, T parameter2) {
  // Function logic using parameters of type T
}

Example: A function to find the maximum of two values:

template <typename T>
T getMax(T a, T b) {
  return (a > b) ? a : b;
}

int main() {
  std::cout << "Max of 3 and 7 is " << getMax(3, 7) << std::endl;
  std::cout << "Max of 3.5 and 2.1 is " << getMax(3.5, 2.1) << std::endl;
  std::cout << "Max of 'a' and 'z' is " << getMax('a', 'z') << std::endl;
}

In this example:

§2 Class Templates #

Class templates allow you to create a template for a class that can handle different data types. Instead of writing separate classes for each data type, you can create one class template that can store and manipulate any type.

Syntax:

template <typename T>
class ClassName {
public:
  T data;
  ClassName(T val) : data(val) {}

  void display() {
    std::cout << "Data: " << data << std::endl;
  }
};

Example: A simple class template to store and display a value of any type.

template <typename T>
class Box {
private:
  T value;

public:
  Box(T v) : value(v) {}

  void show() {
    std::cout << "Box value: " << value << std::endl;
  }
};

int main() {
  Box<int> intBox(123);
  Box<double> doubleBox(45.67);
  Box<std::string> stringBox("Hello, World!");

  intBox.show();
  doubleBox.show();
  stringBox.show();
}
$ ./example
Box value: 123
Box value: 45.67
Box value: Hello, World!

In this example:

The Box class can store any data type, thanks to the template parameter T.

§3 Multiple Template Parameters #

Templates can be defined to accept multiple different types within a single class or function. This allows a function or class to accept and work with more than one type.

When defining a class template that takes multiple types, you can specify each type as a separate template parameter in the template declaration. For example:

// define multiple different template parameters
template <typename T1, typename T2>
class Pair {
private:
  T1 first;
  T2 second;

public:
  Pair(T1 a, T2 b) : first(a), second(b) {}

  T1 getFirst() const {
    return first;
  }

  T2 getSecond() const {
    return second;
  }

  void display() const {
    std::cout << "First: " << first << ", Second: " << second << std::endl;
  }
};

int main() {
  // define each templated type
  Pair<int, std::string> intStringPair(42, "Answer");
  Pair<double, char> doubleCharPair(3.14, 'A');

  intStringPair.display();  // Output: First: 42,   Second: Answer
  doubleCharPair.display(); // Output: First: 3.14, Second: A
}

Here:

§4 Template Specialization #

Sometimes, a generic template does not work well for all types. Template specialization allows you to define a specific implementation of a template for a particular type.

Example: Specializing the Box class to work with the string data type:

template <typename T>
class Box {
public:
  T value;
  Box(T v) : value(v) {}

  void show() {
    std::cout << "Box value: " << value << std::endl;
  }
};

// Template specialization for strings
// we redefine the `Box` class with a specific template implementation for `string` types
template <>
class Box<std::string> {
public:
  string value;
  Box(string v) : value(v) {}

  void show() {
    std::cout << "Specialized Box for string: '" << value << "'" << std::endl;
  }
};

int main() {
  Box<int> intBox(123);
  Box<std::string> stringBox("example");

  intBox.show();    // prints: Box value: 123
  stringBox.show(); // prints: Specialized Box for string: 'example'
}

In this example:

§5 Advantages and Use Cases #

Templates are commonly used for:

Advantages:

§6 Additional Resources: #

§7 Questions #

  1. Provide a short code sample to create a template method/class that can work with two different template types, such as a string and int or a double and float.
  1. Describe a class template and its benefits.
  1. Describe a situation where a class template would be useful.
  1. Why might you need to use template specialization?
  1. What is the syntax to declare a specialized template class to define special behavior for handling a float?