Concepts / Type Aliases

Type Aliases

A template alias is a name that stands for a template or a combination of template arguments.

  • Programming

Why Long Template Names Become Hard to Read

Templates let you write one pattern that works for many types. That flexibility has a cost: the names you write can grow long. A template that takes several type arguments, and that is itself built from other templates, can produce a declaration that is hard to scan. Every place the full name appears, a reader has to parse it again, and every place the name must change, a programmer has to change it.

Type aliases and template aliases are the C++ technique for dealing with this problem. In this article you will watch the state of a name change step by step: first, how a short name is attached to an existing type; second, how a template alias stands for a template with its arguments filled in; and third, how to decide whether an alias actually helps the code you are reading or writing.

A Second Name for the Same Type

Definition

A type alias is a synonym for a type or a template, declared with the keyword using. It gives an existing type or template a second name that means exactly the same thing.

Programs often refer to the same type many times. Sometimes it is useful to introduce a synonym for a type, which is a second name that means exactly the same thing. The same idea also applies to templates, not only to ordinary types. Once the alias exists, the original name and the new name refer to the same thing.

Key point

An alias is a second name for an existing type, so it does not create a separate type. It does not describe a new kind of value, and it does not change how the type behaves.

Reading the using Declaration

Formula, step by step
using type_alias = existing_type;
  1. 1
    The keyword using begins the declaration.
  2. 2
    The new alias name, type_alias, is introduced on the left of the equals sign.
  3. 3
    The existing type, existing_type, is written on the right of the equals sign.
  4. 4
    The semicolon ends the declaration.

The general pattern is that the keyword using is followed by the new alias name, then an equals sign, then the existing type, and finally a semicolon. The alias name always goes on the left of the equals sign and the existing type always goes on the right. The diagram below labels each part of the source declaration. Notice that the existing type is the only thing that already exists before the line is read; the alias name is introduced by the declaration itself.

usingkeyword that starts thedeclarationdistance_tnew alias name, left of ==separates name from meaningdoubleexisting type, right of =;ends the declaration
Which token introduces the new name, which token is the existing type, and which token separates them?

Tracing What size_t Refers To

The standard header <cstddef> contains a definition of the alias size_t. The source gives the following declaration as its example of a type alias. Read this line as: from now on, the name size_t is a synonym for unsigned int. Wherever size_t appears as a type, the compiler treats it exactly as it would treat unsigned int.

Notes on the code
  • The alias name is size_t, on the left of the equals sign.
  • The existing type is unsigned int, on the right of the equals sign.
Worked example

Using an alias for a double-precision distance

The following original illustration defines a new alias named distance_t for double, then uses that alias to declare a variable. What type does the variable have?

  1. 1
    Read the alias declaration

    using distance_t = double; introduces distance_t as a second name for double.

  2. 2
    Read the variable declaration

    distance_t trip = 12.5; declares trip with the name distance_t in the type position.

  3. 3
    Replace the alias with its meaning

    Because distance_t is a synonym for double, the declaration means double trip = 12.5;.

  4. 4
    Check what changed

    No new type was created. The variable behaves exactly like any other double.

Result

trip is an ordinary double. The alias only changed the name used to write the type.

Template Aliases and Their Two Purposes

Definition

A template alias is a name that stands for a template or a combination of template arguments. The source states that template aliases serve two purposes: simplifying notation and hiding implementation details.

A template alias declaration has the same shape as a type alias declaration, with a template parameter list placed in front of it. The reader's first task is to find the right-hand side, because that is the actual meaning, and the left-hand side is simply the name chosen for it. In the generated example below, the alias Pairs takes one type parameter T and stands for Container with T and OtherPolicy as its arguments.

Notes on the code
  • template<typename T> says Pairs takes one type parameter.
  • The right-hand side Container<T, OtherPolicy> is the original template with its arguments.
  • Pairs<double> declares values whose type is Container<double, OtherPolicy>.
Pairs<double>alias used by client codeT = doubleparameter bound to argumentContainer<double,OtherPolicy>original template witharguments filled inargument binds Tsubstituted into right side
When Pairs<double> is written, how does double flow into Container so the result is Container<double, OtherPolicy>?

The mapping from alias arguments to original arguments is the part to check when reading. Whatever you write inside the angle brackets of the alias is substituted for the parameter on the right-hand side, so the full meaning is always the original template with those arguments in its argument list.

When an Alias Helps and When It Clutters

An alias is only worth introducing when it makes a declaration easier to understand or easier to change. An alias that is used once, and whose name adds nothing beyond the original, forces the reader to look up one more name to find the same type. The comparison below summarizes the difference.

SituationAlias helpful?Reason
Long template-id repeated in many placesYesThe alias is written once and read as one meaningful word
Implementation choice may change laterYesClients depend on the alias, so the change is made in one declaration
Short type used in one place with an obvious nameUsually noThe alias adds a name the reader must look up without making the code clearer
Alias name describes nothing beyond the originalUsually noThe reader must still reason about the original type, so the extra name adds a layer

Deciding whether an alias improves a declaration

  • Common mistake

    Reading the left-hand side as the meaning of the alias

    What it looks like

    In using distance_t = double;, reading distance_t as the meaning and ignoring double.

    Why it fails

    The left-hand side is only the chosen name. The right-hand side holds the actual type.

    Do this instead

    Find the right-hand side first and substitute it for the alias name when tracing the code.

  • Common mistake

    Believing an alias creates a new type

    What it looks like

    Expecting size_t to behave differently from unsigned int because it has its own name.

    Why it fails

    An alias is a second name for an existing type. It does not create a separate type with different behavior.

    Do this instead

    Treat size_t exactly as unsigned int wherever it appears as a type.

  • Common mistake

    Forgetting to substitute template arguments into the right-hand side

    What it looks like

    Reading Pairs<double> as Container<T, OtherPolicy> with T left unchanged.

    Why it fails

    The argument in the alias's angle brackets replaces the parameter on the right-hand side.

    Do this instead

    Substitute double for T everywhere it appears on the right-hand side to get Container<double, OtherPolicy>.

  • Common mistake

    Adding an alias for a short type used once

    Why it fails

    The extra name forces a lookup without making the declaration clearer.

    Do this instead

    Write the short type directly when the name adds nothing and the type appears only once.

Predicting What an Alias Means

What do you think happens?

Given the source declaration using size_t = unsigned int; what does the name size_t stand for?

Reveal answer
Answer:

size_t is a synonym for unsigned int.

The alias gives the existing type unsigned int a second name. It does not create a new type, so size_t behaves exactly as unsigned int does wherever it is used as a type.

EASY

Given the declaration template<typename T> using Pairs = Container<T, OtherPolicy>;, write the full template-id that Pairs<double> stands for, and name the alias name and the existing template in the declaration.

Hints
  • Find the right-hand side first: it holds the meaning.
  • Substitute double for T everywhere it appears on the right-hand side.
  • The alias name is on the left of the equals sign and the existing template is on the right.

Summary of Type Aliases

  1. 1
    A template alias is a name that stands for a template or a combination of template arguments, and it serves two purposes: simplifying notation and hiding implementation details.
  2. 2
    A type alias is a synonym for a type or a template, declared with the keyword using in the form using new_name = existing_type; with the new name on the left and the existing type on the right.
  3. 3
    An alias is a second name for the same type. It does not create a new type with different behavior.
  4. 4
    When reading an alias declaration, find the right-hand side first, since it holds the actual meaning, and substitute the alias arguments into it.
  5. 5
    Introduce an alias when it makes a long or repeated name easier to read or easier to change, and avoid an alias that only forces the reader to look up the same type under another name.

At a glance

  • A template alias is a name that stands for a template or a combination of template arguments, and it serves two purposes: simplifying notation and hiding implementation details.
  • A type alias is a synonym for a type or a template, declared with the keyword using in the form using new_name = existing_type; with the new name on the left and the existing type on the right.
  • An alias is a second name for the same type. It does not create a new type with different behavior.
  • When reading an alias declaration, find the right-hand side first, since it holds the actual meaning, and use the template parameter list to see how arguments flow into the original template.
  • Introduce an alias when it makes a long or repeated name easier to read or easier to change, and avoid adding an alias that only forces the reader to look up the same type under another name.

Related concepts

More concepts starting with T