Concepts / Type Aliases and Template Aliasing

Type Aliases and Template Aliasing

A type alias is an alternative name for an existing type, not a new type.

  • Programming

One Line of Code, Many Systems

Programs are often written once and then compiled and run on different systems. A program that works on one system should ideally work on another without its source code being rewritten. This goal is called portability, and it is one of the main reasons programmers use type aliases.

Keep one question in mind as you read: if the same line of source code is built on two different implementations, can the text of that line stay exactly the same while the meaning of the type behind it changes? Type aliases are the feature that makes this possible, and the rest of this article traces how.

Why the Same Type Name Can Mean Different Types

The difficulty begins with types whose exact definition is not fixed. Some types are defined differently by different implementations. This means the same type name can refer to a different underlying type depending on where the program is built.

The source uses size_t as its example. The actual type named size_t is implementation-dependent. In one implementation it may be an unsigned int, while in another implementation the same name may refer to an unsigned long. A programmer reading the code sees the same name in both cases, but the underlying type behind that name is not the same everywhere.

size_twritten identically in thesourceImplementation Aunsigned intImplementation Bunsigned longresolves toresolves to
When the same source line is built on two different implementations, what underlying type does the name size_t resolve to on each one, and does the written name change?

The diagram shows the same written name resolving to different underlying types. Because the code only ever writes the alias, the source text stays identical across both implementations even though the types beneath it differ.

Where Portability Breaks Down

Suppose code uses an implementation-dependent type directly by its underlying name. That code is then tied to one particular implementation. When the program moves to a system where that underlying name refers to a different type, the code no longer describes the situation the author intended, and it must be edited by hand.

How an Alias Sits Between Name and Type

Definition

A type alias is an alternative name for an existing type, not a new type. Writing the alias is the same as writing the type it names, so the alias gives the programmer a convenient label without changing what the type is.

The important point is the direction of the relationship. The alias is the name the programmer writes. The underlying type is the existing type that the name stands for. The arrow points from the name to the type, not the other way around. The alias does not create a second type that happens to behave the same; it is simply another way of spelling the same type.

size_tthe name the programmerwritesUnderlying typethe existing type the namestands forImplementationdecides which type that isis a name for, not a new typedetermines
How does the alias sit between the name used in code and the actual type it refers to, and what decides which type that is?

Tracing One Declaration Across Two Implementations

Here is the central benefit. If code uses an implementation-dependent type directly by its underlying name, that code is tied to one particular implementation. If code uses the alias instead, the alias can be defined to match whatever the current implementation uses. The code that names the alias keeps working without modification, because the programmer never wrote the underlying type name.

Before
unsigned int count = 0;

The declaration names the underlying type directly, so the line is tied to whatever unsigned int means on the one implementation the author had in mind.

After
size_t count = 0;

The declaration names the alias. The same text keeps working on each implementation, because the alias is defined to match the implementation it is built on.

Worked example

Tracing size_t Across Two Builds

The same source line, size_t count = 0;, is compiled on Implementation A and on Implementation B. What changes, and what stays the same?

  1. 1
    Read the source line

    The text size_t count = 0; is identical in both builds. The programmer wrote only the alias, never the underlying type.

  2. 2
    Resolve the alias on Implementation A

    On Implementation A, the name size_t refers to unsigned int, so count is an unsigned int in that build.

  3. 3
    Resolve the alias on Implementation B

    On Implementation B, the same name refers to unsigned long, so count is an unsigned long in that build.

  4. 4
    Compare the two results

    The source text did not change between the builds. Only the underlying type behind the name changed, which is exactly what the alias was designed to allow.

Result

The source line stays identical, and the underlying type follows the implementation. The code moves without any rewriting.

Mistakes That Undo Portability

  • Common mistake

    Writing the underlying type directly instead of the alias

    What it looks like

    unsigned int count = 0; written where the code was meant to use size_t

    Why it fails

    The line now names one specific type and no longer follows the implementation, so the portability benefit is lost for that line.

    Do this instead

    Write the alias so the source text does not name the underlying type.

  • Common mistake

    Assuming an alias always maps to one fixed width

    What it looks like

    Believing size_t is always the same size as unsigned int on every system

    Why it fails

    The source states that the type is implementation-dependent, so the same name may refer to different underlying types on different implementations.

    Do this instead

    Treat the alias as a name whose meaning depends on the implementation, and check the definition on the target platform when the exact type matters.

  • Common mistake

    Treating the alias as a new, separate type

    What it looks like

    Believing that writing size_t creates a distinct type unrelated to the type it names

    Why it fails

    An alias is an alternative name for an existing type, not a new type, so writing the alias is the same as writing the type it names.

    Do this instead

    Remember that the alias and the underlying type are the same type, seen through two names.

  • Common mistake

    Rewriting source code each time the program moves to another system, which defeats the purpose of the alias

Template Aliasing at a Glance

The topic also names template aliasing, which concerns alias templates: aliases that take template parameters. This article focuses on the plain alias, because the grounding for this lesson establishes the core idea: an alias is a name for an existing type, and it lets the source text avoid naming the underlying type.

Tracing an Alias Through a Function Parameter

MEDIUM

A function declares its parameter as unsigned int instead of using the alias size_t. The same source is later built on an implementation where size_t refers to unsigned long. Predict what the declaration is tied to on that implementation, and explain how rewriting the declaration with the alias would prevent the problem.

Hints
  • Ask which name in the declaration is the underlying type and which name the implementation controls.
  • Think about what stays identical in the source text when the alias is used instead of the underlying name.

What do you think happens?

If the alias definition is changed for a new implementation, does code that uses the alias need to be edited?

Reveal answer
Answer:

No. The code that names the alias keeps working without modification, because the programmer never wrote the underlying type name.

The alias can be defined to match whatever the current implementation uses, so the alias is the only place that has to change.

Key Takeaways

  • A type alias is an alternative name for an existing type, not a new type, so writing the alias is the same as writing the type it names.
  • Some types are implementation-dependent: the same name, such as size_t, may refer to unsigned int on one implementation and unsigned long on another.
  • Code that uses the alias instead of the underlying type name can be written once and reused across implementations without modification.
  • Writing the underlying type directly, or assuming a fixed meaning for an alias, weakens portability and reintroduces platform dependence.

Related concepts

More concepts starting with T