На первом курсе ВУЗа нас учили языку Pascal. Пожалуй, лучшее, что удалось взять из Pascal -- это привычку давать имена типам. Полагаю, возникла она потому, что преподаватели хорошенько нам разъясняли почему это правильно, полезно и удобно.
Эта привычка помогала и после перехода на Си, а затем и на C++.
Почему-то мне казалось, что в те старые времена и в Си, и в C++ была культура использования typedef-ов для создания псевдонимов типов. Вероятно из-за того, что платформ было много, платформы были разные. А псевдонимы, сделанные через typedef, помогали справляться с их различием. Достаточно вспомнить приключения при переходе от 16 бит к 32 битам и обратно.
Но сейчас складывается впечатление, что многие C++ разработчики про typedef и using даже и не знают. Вот реально приятно удивляешься, когда открываешь чужой проект -- а там систематическое применение using-ов (или typedef-ов). Обычно же все гораздо печальнее и приходится иметь дело с чем-то вроде:
void do_something(
std::vector<std::pair<int, std::shared_ptr<my_obj>>> & first,
std::map<std::string, std::tuple<int, int, std::string>> & second);
А еще хуже, на мой взгляд, когда один и тот же фундаментальный тип (вроде int-а или unsigned long-а) используется для совершенно разных целей:
struct some_item {
int _x;
int _y;
int _width;
int _height;
int _usage_percentage;
int _reusing_mode;
int _logging_level;
...
};
Когда со временем меняешь int на что-нибудь другое, то обязательно выясняется что где-то как-то параметры перепутали -- выдали _width за _height или _usage_percentage вместо _reusing_mode.
Конечно, от многих подобных проблем в C++ можно было бы избавиться, если бы в C++ из коробки была поддержка strong typedef. Но даже в ее отсутствии обычные псевдонимы типов, сделанные через using, сильно повышают читабельность кода и упрощают его сопровождение (или портирование на другую платформу).
Вроде бы уже не раз говорил в разных местах о достоинствах using-ов:
- сокращение присанины, приведение кода к более лаконичному и, как правило, более понятному виду;
- сокрытие деталей реализации, что помогает затем менять эти самые детали всего лишь в одном месте, но сказываться замена будет автоматически повсюду.
Как по мне, так это более чем очевидно. Поэтому и не буду в очередной раз распространяться.
Но если мне это очевидно, то почему это не очевидно другим C++разработчикам?
Возможно потому, что им не привили правильные привычки во время обучения.
Отсюда проистекает мысль, что если учить людей C++у, то нужно вкладывать им в голову не только идею RAII, как одну из самых основополагающих, но и идею повсеместного применения using-а. А всякий, кто не внемлет мудрости старших, должен быть порот розгами, дабы полезная наука усвоена была, пусть и через другое место.
PS. Очень надеюсь, что рано или поздно, но C++ обзаведется штатным, доступным прямо в стандартной библиотеке, механизмом strong typedef. И если в вашем коде using используется должным образом, то переход к применение strong typedef-а окажется более простым и менее болезненным.