← Back to C++ Course | Chapter 11: Templates | Lesson 3 of 5

C++ Class Templates

A class template is a blueprint with a blank for the type, like a box that can be made to hold apples or oranges. You fill in the type when you use it.
Syntax
cpp
template <typename T>
class ClassName {
public:
  T member;
  T method_name(T param) { return param; }
};

ClassName<type> object_name;

Defining Class Templates

A class template defines a generic class blueprint, letting you build a single data structure — a stack, a container, a wrapper — that can manage elements of any data type instead of being locked to one specific type.

Example: Defining Class Templates

cpp
// Include std::cout and std::cin
#include <iostream>

// Declare a template so this works with any suitable type
template <typename T>
// Define the type Box
class Box {
// Members below can be accessed from outside the class
public:
	T value;
	Box(T v) : value(v) {}
};

// Program execution starts in main()
int main() {
	Box<int> b(5);
	// Print to the console with cout
	std::cout << b.value << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Instantiating Class Templates

To instantiate a class template, you must explicitly specify the data type inside angle brackets when creating an object, since unlike function templates, the compiler generally can't infer a class template's type parameters from constructor arguments alone.

Example: Instantiating Class Templates

cpp
// Include std::cout and std::cin
#include <iostream>

// Declare a template so this works with any suitable type
template <typename T>
// Define the type Box
class Box {
// Members below can be accessed from outside the class
public:
	T value;
	Box(T v) : value(v) {}
};

// Program execution starts in main()
int main() {
	Box<double> b(3.14);
	// Print to the console with cout
	std::cout << b.value << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Defining Member Functions Outside the Body

When defining a class template's member function outside the class body, you have to repeat the full template parameter list as a prefix before the function definition, since the compiler needs that context every time it encounters the definition.

Example: Defining Member Functions Outside the Body

cpp
// Include std::cout and std::cin
#include <iostream>

// Declare a template so this works with any suitable type
template <typename T>
// Define the type Box
class Box {
// Members below can be accessed from outside the class
public:
	T value;
	Box(T v) : value(v) {}
	T getValue();
};

// Declare a template so this works with any suitable type
template <typename T>
T Box<T>::getValue() {
	// Send value back to the caller
	return value;
}

// Program execution starts in main()
int main() {
	Box<int> b(10);
	// Print to the console with cout
	std::cout << b.getValue() << std::endl;
	return 0;
}

Default Template Arguments

You can give a class template's type parameters default types, which lets callers omit the angle-bracket type argument entirely and fall back to a sensible default when they don't need anything more specific.

Example: Default Template Arguments

cpp
// Include std::cout and std::cin
#include <iostream>

// Declare a template so this works with any suitable type
template <typename T = int>
// Define the type Box
class Box {
// Members below can be accessed from outside the class
public:
	T value;
	Box(T v) : value(v) {}
};

// Program execution starts in main()
int main() {
	Box<> b(5);
	// Print to the console with cout
	std::cout << b.value << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Non-Type Parameters in Classes

Class templates also accept non-type parameters, such as integers, which is how fixed-size structures like a compile-time-sized array class can bake their capacity directly into the type itself rather than storing it as ordinary runtime data.

Example: Non-Type Parameters in Classes

cpp
// Include std::cout and std::cin
#include <iostream>

// Declare a template so this works with any suitable type
template <typename T, int Size>
// Define the type FixedArray
class FixedArray {
// Members below can be accessed from outside the class
public:
	T data[Size];
};

// Program execution starts in main()
int main() {
	FixedArray<int, 3> arr;
	arr.data[0] = 10;
	// Print to the console with cout
	std::cout << arr.data[0] << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting the type when creating an object, such as Box b; instead of Box<int> b; (before C++17).
  2. Defining member functions outside the class without repeating template <typename T>.
  3. Putting class template member definitions in a .cpp file, which causes linker errors.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.