Preprocessor Enforced Consistency, хорошая идея в C ++? - PullRequest
1 голос
/ 31 января 2012

Я только что прочитал статью "Идиоматическое программирование" , и он попытался подчеркнуть важную концепцию: язык не должен диктовать, как вы решаете проблему, скорее вы должны диктовать, как язык должен решатьпроблема.

В качестве примера автор выбрал препроцессор C / C ++ для выполнения двух действий:

  1. Обеспечение согласованности

  2. Добавить синтаксис и грамматику к существующему языку.

Теперь я знаю, что эта статья относится как минимум к 2003 году и использует C язык, но я видел, как другие люди использовали по крайней мере пункт 1. раньше (например, Ogre 3D).

В приведенном примере:

#define property(name, type)   :                             \
                            type m##name;                \
                            public:                      \
                             type name()                 \
                                { return m##name; }      \
                             void name(type t__##name)   \
                                { m##name = t__##name; }  

используется так:

class MyClass
{
  protected property(age, unsigned short);
  private   property(gpa, float);

  private:  // Other stuff can go here
};

Помимо того, что макросы являются злом, и мы должны использовать современные варианты C ++, насколько мне известно, не существует подходящего альтернативного решения, и я считаю, что именно такие вещи были созданы Boost.Wave и Boost.Preprocessor.уточнить и улучшить.

Я считаю, что в этом есть некоторые достоинства, но я хотел бы узнать от людей, которые использовали / видели это, что вы думаете?Есть ли у автора точки и пример все еще достоинства, или это что-то, что нужно прочитать, принять к сведению и спрятать как интересный лакомый кусочек?

РЕДАКТИРОВАТЬ

Спасибо за ответы!

Я хочу быстро уточнить природу вопроса.Это не «Этот пример хорошо использовать или нет?»вопрос, это пример типа изменений и расширений, которые автор предлагает обогатить или усовершенствовать существующий язык.Поэтому возникает вопрос: допустимо ли злоупотреблять препроцессором для добавления языковых расширений и обеспечения согласованности на основе примера этого и других фрагментов макроса?

Ответы [ 3 ]

2 голосов
/ 31 января 2012

ИМХО, в этом случае инкапсуляция свойства с помощью макроса не добавляет никакого значения, кроме как слегка запутывает код. Кроме того, вы не можете написать собственный метод получения / установки и оставить другой как есть.

Я делал подобные вещи для некоторых общих шаблонов списков в том месте, где работал два года назад (поищите в моей истории такие теги, как C, macro, препроцессор и удивитесь!: -P

Функциональное программирование на C с макро-генераторами «Функция высшего порядка»

Декораторы функций C (оболочки) во время компиляции ), и теперь я думаю, что это была не самая лучшая идея.

Люди (и инструменты!) Очень легко запутываются, когда вы делаете "умные трюки". Например, в вашем примере есть вероятность, что если кто-то воспользуется его функциями автозаполнения IDE, он не покажет ваши методы или атрибуты.

Так что, если вам действительно не нужно что-то делать умный и мощный , у вас есть подходящие инструменты, и он является идиоматическим в вашей среде (подумайте о Python Модель данных, в которой вы можете иметь дескрипторы свойств или макросы Common Lisp), постарайтесь сделать вещи как можно более явными. Это спасет вас от многих WTF лиц.

1 голос
/ 31 января 2012

этот ум часто ломает инструменты, которые вы используете напрямую.Существуют более четкие решения этой проблемы с использованием языка и основных типов.на самом деле, это быстро разваливается, если значение не может быть скопировано или вы не хотите его копировать.следовательно, необходимые вариации реального мира часто бывают такими же сложными, как и реализации, в которых используются встроенные функции языка, базовые типы и нет магии препроцессора.я использую этот подход, чтобы обойти различия в компиляторе (очень и очень редко) и иногда определять сгенерированные классы (которые затем инкапсулируются и получают надлежащие интерфейсы), и это все.

1 голос
/ 31 января 2012

Итак, если я правильно интерпретирую ваш вопрос - вы хотите знать, является ли хорошей практикой использование установщиков / получателей.

Мой личный опыт заключается в том, что эти методы не добавляют никакой ценности, увеличивайте кодразмер, и не должен использоваться.Вместо этого вы должны сделать эту переменную-член общедоступной.

Однако обратите внимание, что существуют различные мнения по этому вопросу.


Если реализация согласована,тогда это хорошая практика.Но если у вас есть случаи, когда вам нужны разные методы получения / установки, не делайте этого.

...