Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An alias template is a declaration that provides a synonym for a family of types. Introduced in C++11, it combines the template keyword with the using declaration to create parameterized type aliases, overcoming the inability of the legacy typedef specifier to be templated directly.

Syntax

template <template-parameter-list>
using identifier = type-id;
  • template-parameter-list: A comma-separated list of template parameters (type, non-type, or template template parameters).
  • identifier: The name of the alias template.
  • type-id: The target type being aliased, which typically depends on the template parameters.

Type Equivalence

An alias template does not introduce a distinct, new type. When instantiated, the resulting type is strictly equivalent to the type-id with the template arguments substituted for the template parameters. The compiler treats the alias and the underlying type as identical during type checking, overload resolution, and template argument deduction.
#include <type_traits>

template <typename T>
using Pointer = T*;

// Pointer<int> is strictly equivalent to int*
static_assert(std::is_same_v<Pointer<int>, int*>); 

Mechanical Comparison to typedef

Prior to C++11, creating a parameterized alias required wrapping a typedef inside a templated struct or class. Alias templates flatten this structure, removing the need for the typename ... ::type disambiguation syntax. Crucially, alias templates possess a semantic advantage: they can be passed directly as template template arguments. The legacy typedef struct hack cannot be passed to a template expecting a template template parameter without forcing the receiving template to be specifically designed to extract the nested ::type. Legacy typedef approach:
#include <map>
#include <string>

template <typename T>
struct LegacyMapStringKey {
    typedef std::map<std::string, T> type;
};

// Instantiation requires accessing the nested type:
LegacyMapStringKey<int>::type my_map;
Alias Template approach:
#include <map>
#include <string>

template <typename T>
using AliasMapStringKey = std::map<std::string, T>;

// Instantiation is direct:
AliasMapStringKey<int> my_map;
Template Template Argument Comparison:
// A template expecting a template template parameter
template <template <typename> class Container>
struct Consumer {
    Container<int> member; 
};

// Valid: 'member' becomes std::map<std::string, int>
Consumer<AliasMapStringKey> valid_consumer; 

// Flawed: 'member' becomes the wrapper struct LegacyMapStringKey<int>, not the map.
// To support this, Consumer would need to be rewritten to use 'typename Container<int>::type'.
Consumer<LegacyMapStringKey> flawed_consumer; 

Parameter Binding (Partial Aliasing)

Alias templates can bind one or more parameters of an existing template while leaving others open. This creates a new template with a reduced arity.
template <typename T, typename U>
struct Pair { /* ... */ };

// Binds the second parameter to 'int', leaving the first parameter open
template <typename T>
using PairWithInt = Pair<T, int>;

// PairWithInt<double> evaluates to Pair<double, int>

Technical Restrictions and Behavior

  1. No Specialization: Unlike class templates or variable templates, alias templates cannot be explicitly or partially specialized. The substitution must apply uniformly as defined in the primary declaration. If specialization-like behavior is required, it must be implemented in an underlying class template that the alias then refers to.
  2. Template Argument Deduction: When an alias template is used in a function signature, the compiler attempts to deduce the template parameters by substituting the alias with its type-id. If the template parameters can be unambiguously deduced from the expanded type-id, deduction succeeds. If the type-id represents a non-deduced context (e.g., a nested name specifier like typename Traits<T>::type), the alias template also becomes a non-deduced context.
  3. CTAD Integration: As of C++20, Class Template Argument Deduction (CTAD) is supported for alias templates. The compiler automatically synthesizes deduction guides for the alias template based on the deduction guides of the underlying class template being aliased.
  4. Self-Reference: An alias template cannot directly or indirectly refer to itself within its own type-id.
Master C++ with Deep Grasping Methodology!Learn More