Question
In C++ templates, I have seen both of these declarations:
template <typename T>
template <class T>
What is the difference between them?
Also, what do these keywords mean in the following example?
template <template <typename, typename> class Container, typename Type>
class Example
{
Container<Type, std::allocator<Type>> baz;
};
I want to understand when typename and class mean the same thing, and when they serve different purposes in template syntax.
Short Answer
By the end of this page, you will understand that in a template parameter list, typename and class usually mean the same thing when introducing a type parameter. You will also learn the important exception: typename has another role in C++ for disambiguating dependent names. The nested template example will make sense step by step, including how a template template parameter works.
Concept
In C++, both typename and class can be used to declare a type template parameter.
For example, these are equivalent:
template <typename T>
class Box;
template <class T>
class Box;
In both cases, T stands for a type such as int, std::string, or a user-defined class.
When they mean the same thing
Inside a template parameter list, typename and class are interchangeable for naming a type parameter:
template <typename T>
void func(T value);
template <class T>
void func(T value);
Mental Model
Think of a template like a form with blanks to fill in.
typename Torclass Tmeans: “fill this blank with a type.”template <typename, typename> class Containermeans: “fill this blank with a template that itself needs two type blanks.”
So there are two levels:
- A blank for a normal type, like
int - A blank for a template, like
std::vector
A simple analogy:
typename Tis like asking for a material: wood, steel, plastictemplate <typename, typename> class Containeris like asking for a blueprint that can build something once you provide materials
Then this line:
Container<Type, std::allocator<Type>> baz;
says: use the blueprint Container, fill in the type Type and an allocator, and create an object named baz.
Syntax and Examples
Basic syntax
Type template parameter using typename
template <typename T>
class Box {
public:
T value;
};
Type template parameter using class
template <class T>
class Box {
public:
T value;
};
These mean the same thing.
Example: both forms are equivalent
#include <iostream>
template <typename T>
T square1(T x) {
return x * x;
}
template <class T>
T square2(T x) {
return x * x;
}
int main {
std::cout << <>() << ;
std::cout << <>() << ;
}
Step by Step Execution
Consider this example:
#include <vector>
#include <memory>
template <template <typename, typename> class Container, typename Type>
class Example {
public:
Container<Type, std::allocator<Type>> baz;
};
int main() {
Example<std::vector, int> ex;
ex.baz.push_back(10);
ex.baz.push_back(20);
}
Step-by-step
1. The template is declared
template <template <typename, typename> class Container, typename Type>
This says Example needs:
Container: a class template that takes two type parameters
Real World Use Cases
Generic containers and wrappers
You may want a class to work with different container templates:
std::vectorstd::list- custom container templates
Reusable library components
Library code often accepts types and templates as parameters so the user can customize behavior without rewriting logic.
Allocator-aware code
The example uses std::allocator<Type>, which is relevant in codebases that care about memory allocation strategy.
Policy-based design
A class may accept templates that define behavior, storage, or configuration.
Generic algorithms
Understanding typename is essential when writing algorithms that depend on nested types such as:
T::value_typeT::iteratorT::const_iterator
Example:
template <typename Container>
typename Container::value_type lastValue(const Container& c) {
c.();
}
Real Codebase Usage
In real C++ projects, developers use these ideas in a few common ways.
1. Generic type parameters
This is the most common usage:
template <typename T>
class Result {
T value;
};
This appears in utility classes, containers, wrappers, and algorithms.
2. Dependent nested types
This is extremely common in generic code:
template <typename Container>
void process(const Container& c) {
typename Container::const_iterator it = c.begin();
(void)it;
}
3. Validation through template shape
Template template parameters let APIs require a specific template form:
template <template <typename, typename> class Seq, typename T>
class Buffer {
Seq<T, std::allocator<T>> data;
};
4. Early constraints by interface shape
Common Mistakes
Mistake 1: Thinking class means only user-defined classes
Wrong idea:
template <class T>
T add(T a, T b);
Some beginners think T must be a class type. That is false.
This works with built-in types too:
add<int>(1, 2);
Mistake 2: Forgetting typename for dependent types
Broken code:
template <typename T>
void f() {
T::value_type x;
}
Fix:
template <typename T>
void f() {
typename T::value_type x;
}
Why: the compiler needs to know is a type.
Comparisons
| Concept | Meaning | Where used | Notes |
|---|---|---|---|
typename T | T is a type parameter | Template parameter lists | Equivalent to class T here |
class T | T is a type parameter | Template parameter lists | Historical syntax; still valid |
typename T::value_type | T::value_type is a type | Inside template definitions | typename may be required |
class T::value_type | Invalid in this context |
Cheat Sheet
Quick rules
- In a template parameter list,
typenameandclassusually mean the same thing. - Both can declare a type parameter.
typenameis also used elsewhere to mark a dependent name as a type.classcannot be used for that second purpose.
Equivalent forms
template <typename T>
class A;
template <class T>
class A;
When typename is required
template <typename T>
void f() {
typename T::value_type x;
}
Template template parameter syntax
template <template <typename, typename> class , T>
{
Container<T, std::allocator<T>> data;
};
FAQ
Is there any difference between typename and class in template <...>?
In a template parameter list for a type parameter, no. They mean the same thing.
Should I prefer typename or class in C++ templates?
Many developers prefer typename because it is clearer that the parameter can be any type, not just a class. But both are correct.
Why does typename sometimes appear before T::value_type?
Because T::value_type is a dependent name. The compiler needs typename to know it refers to a type.
Can I use class instead of typename before T::value_type?
No. That use is specific to typename.
What is a template template parameter?
It is a template parameter that accepts another template as an argument.
What does template <template <typename, typename> class Container> mean?
Mini Project
Description
Build a small generic wrapper class that can store values inside a container template such as std::vector. This project demonstrates two key ideas from the question: regular type template parameters and template template parameters. It also helps you read and write nested template syntax with more confidence.
Goal
Create a reusable class that accepts a container template and a value type, stores values, and prints the number of stored items.
Requirements
- Create a class template that accepts a container template and a type parameter.
- Store data using the provided container with
std::allocator. - Add a method to insert values into the container.
- Add a method to return the number of stored elements.
- Instantiate the class with
std::vectorandintinmain().
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.