Хочу поделиться многолетним опытом. Работает на 100%, а иногда и на все 146%. Так смело можете брать на вооружение, если решили конкретно поднасрать своим коллегам.
Во-первых, используйте std::pair и std::tuple для долгоживущих объектов. Особенно если эти объекты свободно перемещаются между различными частями программы.
Поверьте, настоящие программисты (тм) всегда будут точно знать, что означают it->first или std::get<3>(*it).
Наверняка на вашем пути встретятся душнилы, которые будут утверждать, что std::pair и std::tuple нужно ограничивать очень маленьким скоупом. Вроде возвращаемого значения лямбда-функции или же обычной вспомогательной функции, но которая вызывается всего в одном-двух местах. А для всего остального нужно создавать нормальные структуры с названиями полей, соответствующими предметной области.
Не обращайте на них внимания. Это же склеротики, которые не могут удержать в памяти даже два простых названия -- first и second, хотя что может быть проще? Ну и наверняка им платят за строчки кода, а не за решение проблем. Вот они и фигачат по 100500 строк там, где можно обойтись одним std::pair-ом.
Во-вторых, забудьте такую вещь, как strong typedef. Тем более, что в C++ из коробки ее и нет. Так что это вообще не ваш путь, а те, кто про пытается заикаться о strong typedef, просто учились программировать на Pascal-е, а значит старпёры и ничего не понимают в современной разработке софта.
Если у нас есть строковое имя пользователя и строковый же пароль в виде открытого текста, то достаточно простого std::string.
Вводить какие-то новые типы UserName и PlainTextPassword? Ради чего? Ради того, чтобы случайно не пихнуть пароль туда, где ожидается имя пользователя?
Да это вообще смешно. Ведь так никто не делает. А если вдруг, так это от кривизны рук. Настоящие программисты (тм) таких ошибок не допускают.
Но даже если какой-то джуниор-разработчик такую ошибку допустит, то он же сам себе злобный буратино, да и тестами все это ловится на раз-два.
Так что никаких strong typedef-ов. Забудьте как страшный сон.
Ну и в качестве бонуса: вам не нужны ни using, ни typedef. Если у вас есть map, значением которого будет vector из queue, то вот прямо так и нужно записывать. Никаких вспомогательных using-ов и typedef-ов!
Ну а самые прозорливые читатели могли догадаться, что все эти советы легко комбинируются. Ведь это так просто:
void process_appropriate_items( const std::vector< std::pair< std::pair<int, int>, std::tuple<std::string, std::string, std::string, std::string> > > & what) { for(const auto & p : what) if(p.first.second > 0) process(std::get<3>(p.second)); } |
Зачем выдумывать что-то еще? Неужели вам не понятно что означает p.first.second и std::get<3>(p.second)? Да ну, не может такого быть!
Перестрахуюсь на всякий случай: в каждой фразе здесь должен быть тег "сарказм". Иногда и не один.
3 комментария:
Еще в копилочку надежных методов можно добавить использование union-ов.
Запихнул элемент в юнион, и естественно, в любой точке программы ты помнишь, из какого под-юниона его нужно извлечь
@sv
Эт да, не поспоришь.
Но я пишу о том, что вижу постоянно.
А вот union, к счастью, видеть приходится очень и очень редко.
Значит, это мне так повезло...
Отправить комментарий