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
andtypename
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