Псевдонимы типов: using и typedef
У многих людей есть имя и прозвище: Александра друзья зовут Сашей, но человек от этого один. Псевдоним типа — такое же второе имя для существующего типа. Компилятор видит за ним тот же самый тип, а вам короткое понятное имя помогает читать код.
Зачем это нужно? Имя long long ничего не говорит о том, что в переменной лежат очки игрока, а std::vector<long long> долго писать в каждом объявлении.
Две записи псевдонима
Запись через using
Псевдоним вводят через using: using Score = long long;. Новое имя стоит слева от =, как в присваивании, а справа — тип, который оно обозначает.
Запись через typedef
Старая запись того же псевдонима досталась от языка C: typedef long long Score;. Новое имя в ней стоит в конце, после типа.
Давайте посмотрим на обе записи в одной программе:
#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
}Разберём по шагам:
using Score = long long;—Scoreтеперь означаетlong long.typedef std::vector<Score> ScoreList;—ScoreListозначаетstd::vector<long long>: псевдоним можно строить из другого псевдонима.- Сумма двух чисел
1500000000не поместилась бы вint, ноScore— этоlong long, поэтому программа печатает3000000000.
Тот же тип под другим именем
Псевдоним не создаёт новый тип: для компилятора Score — это long long, а ScoreList — std::vector<long long>. Значения под старым и новым именем свободно смешиваются в одном выражении.
Зато псевдоним делает код понятнее: чтобы сменить тип во всей программе, вы правите одну строку using.
В отличие от #define, псевдоним подчиняется области видимости: объявленный внутри функции, он виден только в ней. Здесь аналогия с прозвищем заканчивается: прозвище у человека остаётся везде, а такой псевдоним за закрывающей скобкой функции исчезает.
Частая ошибка
От псевдонимов ждут защиты от путаницы единиц:
#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); // ✗
}Компилятор молча собирает программу, и она печатает 212 как температуру по Цельсию. Celsius и Fahrenheit объявлены псевдонимами double, поэтому функция с параметром Celsius принимает Fahrenheit без единого предупреждения. Псевдоним от такой ошибки не защищает: держите единицу в имени переменной, например boiling_f, чтобы путаницу было видно при чтении.
Главное
- Псевдоним типа — второе имя существующего типа:
using Score = long long;. typedef long long Score;— старая запись того же псевдонима, новое имя в ней стоит в конце.- Псевдоним не создаёт новый тип: значения двух псевдонимов
doubleсвободно смешиваются. - Псевдоним подчиняется области видимости, а
#define— нет.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.