Template Compilation Model
An alias is a name tied to the original template, not an independent copy of it. Changing the meaning of the original template is a different matter from defining a new name for it, and the alias only refers back to the original.
Why Repeating Arguments Becomes a Problem
Imagine a template that takes two type arguments, but in your program you almost always use the same type for one of them. Every time you want a value of that template, you must write out both arguments, even though one of them never changes. Repeating that fixed argument is tedious, and it makes the code harder to read. A template alias is a way to deal with this situation.
What do you think happens?
If you fix one of two template arguments, how many arguments does the new template still need when you use it?
Reveal answer
One. The argument that was not fixed is still open, so the user supplies only that one.
A template alias defines a new template by binding some of the arguments of an existing template. Whatever is not bound remains the user's responsibility at the point of use.
Tracing a Template Without an Alias
Start with the original template, which takes two type arguments. The example below is illustrative and written for this article. Its syntax follows the C++ template style. Notice how the second argument, int, is written out in every use even though it never changes.
Each line names the same template and repeats int in the second position. The only thing that changes from line to line is the first argument. This is exactly the repetition that a template alias is meant to remove.
What a Template Alias Binds
A template alias defines a new template by binding some or all of the template arguments of an existing template.
The key word is binding. Binding means that a particular argument is given a fixed value inside the alias, so the learner no longer supplies it when using the alias. The alias is not a copy of the original template and it is not a new kind of value. It is a new name for a template in which some or all of the arguments have already been decided.
An alias is a name tied to the original template, not an independent copy of it. Changing the meaning of the original template is a different matter from defining a new name for it, and the alias only refers back to the original.
Anatomy of an Alias Declaration
The following illustrative declaration defines a new template from the Pair template above. It binds the second argument to int and leaves the first argument open.
Read the declaration from left to right. The template parameter list says that the new name still takes one argument of its own, called T. The new name PairWithInt is what you use in your program. The right-hand side, Pair<T, int>, is the bound template-id that refers to the original template, with the second argument already fixed to int.
Partial Versus Full Binding
The description allows two cases. In partial binding, only some arguments are bound, so the new template still takes arguments of its own. In full binding, all arguments are bound, so nothing is left for the user to supply. Both cases are still an alias: the new name is defined in terms of the original template with its arguments fixed in place.
In the full-binding example, both arguments are fixed, so IntPair names one fully specified type and the declaration IntPair a; supplies no template arguments. The source gives no separate rule for this case, so the only thing to take from it is what the general description already states: the alias binds all of the arguments.
Mapping Alias Parameters to Argument Positions
When an alias fixes some arguments and leaves others open, the most important question is which parameter of the new template feeds into which position of the original template. In PairWithInt, the single parameter T feeds the first position of Pair, and the fixed value int occupies the second position.
Reading an alias declaration
Given the declaration template <typename U> using PairWithDouble = Pair<double, U>;, which argument does the user supply, and which position is fixed?
- 1Identify the new name
The alias is named PairWithDouble.
- 2Identify the open parameter
The parameter list declares U, so the user supplies one argument when using the alias.
- 3Identify the bound position
The first position of Pair is fixed to double, because it is the first argument in Pair<double, U>.
- 4Map the open parameter
U feeds the second position of Pair, so the user's argument becomes the second argument.
The user supplies one type, and it becomes the second argument of Pair. The first argument is always double. For example, PairWithDouble<char> is a Pair whose first argument is double and whose second argument is char.
Mistakes Learners Make with Aliases
Common mistake Treating the alias as a separate copy of the original template
Why it failsThe source states that an alias is a name tied to the original template, not an independent copy of it.
Do this insteadThink of the alias as a new name for the original template with some or all of its arguments already decided.
Common mistake Supplying the bound argument again when using the alias
What it looks likePairWithInt<double, int> a;Why it failsThe alias has already fixed the second argument to int, so only the open argument is supplied at the point of use.
Do this insteadWrite PairWithInt<double> a; and let the alias supply int.
Common mistake Assuming the parameter order of the alias matches the order of the original template by default
Why it failsEach parameter of the alias must be placed in the right argument position of the original. Putting the open parameter in the wrong place binds the wrong argument.
Do this insteadMap each alias parameter explicitly to its position in the bound template-id, as in Pair<T, int> where T is the first argument.
Common mistake Expecting a fully bound alias to still take arguments
What it looks likeusing IntPair = Pair<int, int>; IntPair<double> a;Why it failsWhen all arguments are bound, the alias has no open arguments left, so nothing is supplied at the point of use.
Do this insteadUse IntPair a; with no template arguments.
Practice Defining an Alias
Using the Pair template from this article, write a template alias named PairWithChar that binds the first argument to char and leaves the second argument open. Then write one line that declares a variable of type PairWithChar using the second argument as double.
Hints
- Your alias needs a template parameter list that declares one open parameter.
- The bound template-id should be Pair<char, T> if T is the open parameter.
- The use of the alias supplies only the open argument, so it should look like PairWithChar<double>.
Summary of Template Aliases
- 1A template alias defines a new template by binding some or all of the template arguments of an existing template.
- 2Partial binding leaves some arguments open, so the user supplies only those when using the alias.
- 3Binding all arguments produces an alias that needs no template arguments at the point of use.
- 4An alias is a name tied to the original template, not an independent copy of it.
At a glance
- A template alias defines a new template by binding some or all of the template arguments of an existing template.
- Partial binding leaves some arguments open, so the user supplies only those when using the alias.
- Binding all arguments produces an alias that needs no template arguments at the point of use.
- An alias is a name tied to the original template, not an independent copy of it.