Я работал над основополагающей библиотекой C++ в течение некоторого времени теперь, и существует множество идей, которые я имел, который мог действительно упростить запись кода и управление процессом. Один из них является понятием представления некоторых макросов, чтобы помочь упростить операторы, которые появляются очень часто, но немного более сложны, чем должно быть необходимым.
Например, я придумал этот основной макрос для упрощения наиболее распространенного типа для цикла:
#define loop(v,n) for(unsigned long v=0; v<n; ++v)
Это позволило бы Вам заменить неуклюжих для циклов, из которых Вы видите большую часть из:
for (int i = 0; i < max_things; i++)
С чем-то намного более легким для записи, и даже немного более эффективный:
loop (i, max_things)
Действительно ли это - хорошая идея использовать конвенции как это? Есть ли какие-либо проблемы, с которыми Вы могли бы столкнуться с различными типами компиляторов? Это просто слишком сбивало бы с толку кого-то незнакомого с макросом (макросами)?
ИМХО, это вообще плохая идея. По сути, вы меняете хорошо известный и понятный синтаксис на что-то свое собственное изобретение. Вскоре вы можете обнаружить, что заново изобрели язык . :)
Я думаю, что вы предоставили один сильный аргумент против этого макроса в вашем примере использования. Вы изменили тип итератора цикла с int
на unsigned long
. Это не имеет ничего общего с тем, сколько вы хотите набирать, так зачем его менять?
Этот громоздкий цикл for определяет начальное значение, конечное значение, тип и имя итератора. Даже если мы предположим, что последней частью всегда будет ++ name
, и мы будем счастливы придерживаться этого, у вас есть два варианта - убрать некоторую гибкость или каждый раз вводить все это. Вы решили убрать гибкость, но, похоже, вы также используете эту гибкость в своей кодовой базе.
В Unix я обнаружил, что к тому времени, когда я хочу создать псевдоним для команды, которую использую все время, команда уже у меня на пальцах, и Мне было бы труднее запомнить синтаксис моего псевдонима, чем исходной команды.
То же самое применимо и здесь - к тому времени, когда вы так часто используете идиому, что вы захотите создать для нее макрос, идиома окажется у вас на пальцах и причинит вам больше боли, чем просто набор кода.
Стив Джессоп хорошо замечает. У макросов есть свое применение. Если я могу разъяснить его утверждения, я бы пошел еще дальше и сказал, что аргумент за или против макросов сводится к «Это зависит от обстоятельств». Если вы создадите макросы без тщательного обдумывания, вы рискуете усложнить жизнь будущим специалистам по обслуживанию. С другой стороны, использование библиотеки wxWidgets требует использования предоставленных библиотек макросов для соединения вашего кода с библиотекой gui. В этом случае макросы снижают входной барьер для использования библиотеки, поскольку магия, внутренность которой не имеет отношения к пониманию того, как работать с библиотекой, скрыта от пользователя. В этом случае пользователь избавляется от необходимости понимать вещи, о которых ему действительно не нужно знать, и можно утверждать, что это «хорошее» использование макросов. Кроме того, wxWidgets четко документирует, как предполагается использовать эти макросы. Так что убедитесь, что то, что вы скрываете, не нужно понимать кому-то еще.
Или, если это только для вашего использования, вырубите себя.
Избавление от циклов for обычно является хорошей идеей, но замена их макросами - нет. Вместо этого я бы долго и внимательно изучил алгоритмы стандартной библиотеки.
Вопрос в том, где вы получаете свою ценность. Действительно ли набор этих 15 дополнительных символов в циклах замедляет ваше развитие? Возможно нет. Если у вас повсюду появляется несколько строк запутанного, неизбежного шаблона, вы можете и должны искать способы избежать повторения, например, создавать полезные функции, очищать иерархию классов или использовать шаблоны.
Но к написанию кода применяются те же правила оптимизации, что и к его запуску: оптимизация мелких вещей с небольшим эффектом - это не очень хорошее использование времени или энергии.
Помимо проблем с обслуживанием / пониманием, упомянутых другими, вам также будет сложно сломать и выполнить пошаговый код макроса.
Я думаю, что макросы могут быть приемлемы для заполнения больших структур данных константами / литералами (когда это может сэкономить чрезмерное количество набора текста). Обычно такой код не выполняется пошагово.
Нет, плохая идея.
int max = 23;
loop(i, ++max)...
Однако рекомендуется реорганизовать часто используемый код в повторно используемые компоненты, а затем повторно использовать его вместо копирования. Вы должны сделать это, написав функции, аналогичные стандартным алгоритмам, таким как std :: find (). Например:
template < typename Function >
void loop(size_t count, Function f)
{
for (size_t i = 0; i < count, ++i) f();
}
Это гораздо более безопасный подход:
int max = 23;
loop(++max, boost::bind(....));
Я бы сказал, это зависит от того, ожидаете ли вы, что кто-нибудь когда-либо нужно разобраться в вашем коде. Если там будете только вы, тогда я не вижу проблем с макросами.
Если кому-то еще когда-нибудь придется взглянуть на этот код, то макросы вызовут проблемы.Другой человек не будет знать, что они из себя представляют и что они делают (независимо от того, насколько понятными и очевидными они кажутся вам), и ему придется отправиться на охоту за ним, когда они впервые столкнутся с ними. В результате ваш код станет недоступным для чтения никому, кроме вас самих - любому, кто его использует, по сути, придется изучать новый язык и программу одновременно.
И поскольку шансы, что вы имеете дело с кодом, практически равны нулю, если вы надеетесь, что код будет библиотекой, предназначенной не только для вашего личного использования, то я бы выбрал don 'т .