Typename vs Class in Template Declarations

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

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.

Class Templates

Learn how templates can be used to create multiple classes from a single blueprint

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Partial Specialization of Class Templates
Is it possible to partially specialize a class template?
Compile-Time Polymorphism with Templates
Can I use templates to implement compile-time polymorphism?
Creating Templates with Variable Number of Parameters
How can I create a template that works with an arbitrary number of type parameters?
Default Values for Non-Type Template Parameters
Is it possible to have default values for non-type template parameters?
Constraining Template Arguments
How can I create a template that only accepts certain types of arguments?
Creating Class Templates with Multiple Types
How can I create a class template that works with both primitive types and user-defined types?
Best Practices for Naming Template Parameters
What are the best practices for naming template parameters?
Specializing Class Templates
How can I specialize a class template for specific types?
Using Template Parameters in Constructors
Can I use template parameters in the constructor of a class template?
Template Methods in Non-Template Classes
How do I create a template method within a non-template class?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant