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
classimplies that the type parameter should be a class or struct.typenamemore 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
classandtypenameare allowed.
Dependent Names
typenameis 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: 8Best 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