๐ŸŽ“ A1Learner
๐Ÿ”
0 of 34 lessons completed

C++ Template Specialisation

Template specialisation gives one chosen type its own version of a template. The primary template still serves every other type.

The primary printer

Printer prints a value after a label. The same primary template serves an int and a double.

#include <iostream>

template <typename T>
class Printer {
public:
  void print(T value) {
    std::cout << "Value: " << value << "\n";
  }
};

int main() {
  Printer<int> forInts;
  Printer<double> forDoubles;
  forInts.print(42);
  forDoubles.print(2.5);
  return 0;
}

A special version for bool

The bool specialisation prints words instead of a value. The int call still uses the primary template.

#include <iostream>

template <typename T>
class Printer {
public:
  void print(T value) {
    std::cout << "Value: " << value << "\n";
  }
};

template <>
class Printer<bool> {
public:
  void print(bool value) {
    if (value) {
      std::cout << "Switch: on\n";
    } else {
      std::cout << "Switch: off\n";
    }
  }
};

int main() {
  Printer<int> forInts;
  Printer<bool> forBools;
  forInts.print(42);
  forBools.print(true);
  forBools.print(false);
  return 0;
}

A defaulted type parameter

The addTen template defaults its type to int. One call names no type and one call names double.

#include <iostream>

template <typename T = int>
T addTen(T value) {
  return value + 10;
}

int main() {
  std::cout << "Default: " << addTen(5) << "\n";
  std::cout << "Named: " << addTen<double>(2.5) << "\n";
  return 0;
}

Example

#include <iostream>

template <typename T>
class Printer {
public:
  void print(T value) {
    std::cout << "Value: " << value << "\n";
  }
};

template <>
class Printer<bool> {
public:
  void print(bool value) {
    if (value) {
      std::cout << "Switch: on\n";
    } else {
      std::cout << "Switch: off\n";
    }
  }
};

int main() {
  Printer<int> forInts;
  Printer<double> forDoubles;
  Printer<bool> forBools;
  forInts.print(8);
  forDoubles.print(4.75);
  forBools.print(true);
  return 0;
}

Key points

  • The primary template holds the general behaviour.
  • A full specialisation replaces the whole template for one type.
  • A full specialisation starts with a template line that has empty angle brackets.
  • Calls with the specialised type use the special version.
  • Calls with other types keep using the primary template.
  • A function template can give a type parameter a default type.

In this example, one printer serves three types. The int and double calls use the primary template. The bool call uses the specialisation and prints a word.

Note

Partial specialisation and deeper template tools belong to a later course.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What marks a full specialisation of a class template?