Class Templates

Typename vs Class in Template Declarations

What's the difference between typename and class in template parameter declarations?

Illustration representing computer hardware

The class keyword was introduced in the original C++ template syntax, and was Initially used for all template type parameters.

The typename keyword was introduced later to clarify that the template parameter could be any type, not just a class.

In template parameter declarations, typename and class are often interchangeable, but there are some subtle differences and historical reasons for their usage Let's explore the differences and when to use each.

Functional Differences

In most cases, typename and class can be used interchangeably in template parameter declarations. However, there are a few key differences:

Semantics

  • class implies that the type parameter should be a class or struct.
  • typename more accurately conveys that the parameter can be any type, including fundamental types, pointers, or classes.

Template Template Parameters

  • When declaring a template template parameter, you must use class (before C++17).
  • From C++17 onwards, both class and typename are allowed.

Dependent Names

  • typename is required when referring to a dependent type name inside a template (not in the parameter list).

Here's an example illustrating these points:

#include <iostream>
#include <vector>

// These are equivalent
template <typename T>
void func1(T t) {
  std::cout << t << '\n';
}

template <class T>
void func2(T t) {
  std::cout << t << '\n';
}

// Template template parameter (pre-C++17)
template <template <class> class Container>
void func3(Container<int>& c) {
  std::cout << "Container size: "
    << c.size() << '\n';
}

// Dependent type name
template <typename T>
void func4() {
  // 'typename' required here
  typename T::value_type val;
  std::cout << "Type size: "
    << sizeof(val) << '\n';
}

int main() {
  func1(42);
  func2("Hello");

  std::vector<int> vec = {1, 2, 3};
  func3(vec);

  func4<std::vector<double>>();
}
42
Hello
Container size: 3
Type size: 8

Best Practices

While typename and class are often interchangeable, there are some guidelines for their usage:

Prefer typename for General Type Parameters

It's more accurate and doesn't imply that the type must be a class.

template<typename T>
void func(T t) {/* ... */ }

Pre-C++17

Use class for template template parameters if targeting pre-C++17

template<template<class> class Container>
void func(Container<int>& c) {/* ... */}

Dependent Type Names

Always use typename for dependent type names within a template

template<typename T>
void func() {
  typename T::value_type val;
  // ...
}

Be Consistent Within Your Codebase

  • If your project has a style guide, follow it.
  • If you're working on existing code, match the existing style.

Consider Readability

In some cases, class might be more readable, especially when working with class-like concepts.

In modern C++, typename is generally preferred for its clarity and accuracy. However, both keywords remain in use, and understanding their subtle differences can help you write more expressive and correct template code.

Answers to questions are automatically generated and may not have been reviewed.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 125 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved