Type aliases: using and typedef
Many people have a name and a nickname: friends call Alexander "Sasha", yet there is still only one person. A type alias is the same kind of second name for an existing type. The compiler sees the very same type behind it, while a short, clear name helps you read the code.
Why is this useful? The name long long says nothing about the variable holding a player's score, and std::vector<long long> takes a while to write in every declaration.
Two ways to write an alias
With using
An alias is introduced with using: using Score = long long;. The new name is to the left of =, as in an assignment, and the type it stands for is on the right.
With typedef
The older notation for the same alias comes from C: typedef long long Score;. There the new name comes last, after the type.
Let's see both notations in one program:
#include <iostream>
#include <vector>
using Score = long long;
typedef std::vector<Score> ScoreList;
int main() {
ScoreList scores{1500000000, 1500000000};
Score total = scores[0] + scores[1];
std::cout << total << '\n'; // 3000000000
}Step by step:
using Score = long long;:Scorenow meanslong long.typedef std::vector<Score> ScoreList;:ScoreListmeansstd::vector<long long>, so an alias can be built from another alias.- The sum of two
1500000000values would not fit in anint, butScoreislong long, so the program prints3000000000.
The same type under another name
An alias does not create a new type: to the compiler, Score is long long, and ScoreList is std::vector<long long>. Values under the old name and the new one mix freely in one expression.
What an alias does give you is clearer code: to change the type for the whole program, you edit one using line.
Unlike #define, an alias obeys scope: declared inside a function, it is visible only there. This is where the nickname analogy ends: a person keeps a nickname everywhere, while such an alias disappears past the function's closing brace.
Common mistake
Aliases are expected to guard against mixing up units:
#include <iostream>
using Celsius = double;
using Fahrenheit = double;
void print_celsius(Celsius t) {
std::cout << t << '\n';
}
int main() {
Fahrenheit boiling = 212.0;
print_celsius(boiling); // ✗
}The compiler builds the program silently, and it prints 212 as a Celsius temperature. Celsius and Fahrenheit are both declared as aliases of double, so a function with a Celsius parameter accepts a Fahrenheit without a single warning. An alias does not protect against this mistake: keep the unit in the variable's name, such as boiling_f, so the mix-up shows when you read the code.
Key points
- A type alias is a second name for an existing type:
using Score = long long;. typedef long long Score;is the older notation for the same alias, with the new name last.- An alias does not create a new type: values of two
doublealiases mix freely. - An alias obeys scope, and
#definedoes not.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.