Существуют ли альтернативы метапрограммированию на С ++ помимо шаблонов? - PullRequest
5 голосов
/ 11 января 2011

Я довольно часто использую метапрограммирование, но иногда комбинации макросов и шаблонов c просто недостаточно.

Я полагаю, что недостатком может быть отсутствие кроссплатформенной совместимости, если платформа метапрограммированиятолько для, скажем, linux и т. д.

Так что да, есть ли такая вещь прямо сейчас, кроме шаблонов?В поиске метапрограммирования в Google преобладает метапрограммирование шаблонов, поэтому сейчас его сложно найти.

edit : вот пример того, над чем я работал.

Предположим, у меня есть общий класс для сохранения / загрузки файлов в буферы и из них.Давайте назовем его FilePack.

У меня есть макрос для определения, который выглядит как

  defineFilePack(BaseClass, "code-a")

Он в основном создает класс с именем «BaseClassPack», который определен как подкласс.Ниже эта вещь.

class FilePack{
   public:
      char * thebuffer;
      int bufsize;
      string packcode;

      // and constructors etc
      FilePack(const string& thecode, int bufsize);
      void operator=(FilePack& rhs);
      void saveToFile(const string& filename);
      void loadFromFile(const string& filename);
      // .. and all the function you'd expect to see in a class like this

};

// the person details

class PersonDetails{
   public:
      solidstring<64> name;
      int age;
      DateTime birthday;
      // .. yada yada yada
};


defineFilePack(PersonDetails, "psd")

// the above creates the following class

class PersonDetailsPack : public FilePack{
   public:
      PersonDetailsPack():
         FilePack("psd", sizeof(PersonDetails)){ // etc

      }

      PersonDetails& get(){
         return *(PersonDetails*)getBuffer();
      }

      // and a lot more convenience function

};

Теперь, по сути, есть встроенная проверка конструктора FilePack, что объявленный код соответствует размеру, с использованием глобальной карты.

Прямо сейчас я нахожусь в тупике о том, какСделайте это, используя шаблонное метапрограммирование, которое на самом деле хорошо подходит для этого, потому что все эти коды файловых пакетов объявлены внутри исходного файла.Конечно, кто-то может сделать свой собственный FilePack во время выполнения, но это не главное.

Еще одна вещь, с которой здесь может помочь метапрограммирование, - поддержка загрузки различных версий FilePack.Предположим, мне пришлось обновить класс PersonDetails. Я просто создаю новый класс, использую какое-то метапрограммирование для объявления наследования и волшебным образом заставляю FilePack знать, чтобы при загрузке старой версии PersonDetails он мог вызывать функцию преобразования, иличто угодно.

Кроме того, вы можете прокомментировать эту архитектуру, и я хотел бы услышать какие-либо комментарии о ней, но это может быть немного не по теме?

Ответы [ 5 ]

5 голосов
/ 11 января 2011

Вы также можете метапрограммировать с препроцессором.

Вы можете рассмотреть возможность использования препроцессоров специального назначения для генерации кода как «метапрограммирования».Тогда вы можете включить такие вещи, как lex / yacc и Qt MOC.

2 голосов
/ 11 января 2011

Если вы определяете метапрограммирование как написание кода, который генерирует код, то у вас есть

  • Шаблоны.
  • Препроцессор.
  • Другая предварительная обработка (обычно скрипты, но иногда расширение компилятора)
  • Генерация исходного кода C ++ из кода C ++, компиляция на лету, загрузка в качестве разделяемой библиотеки.
  • Возможно, но это растягивает его, а также генерирует машинный код, как окурки батута.

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

Насколько я помню, ParcPlace сделал инструмент для этого?

Хм, это напоминает мне не забывать когда-нибудь проверить это. : -)

Приветствия и hth.,

2 голосов
/ 11 января 2011

Внутри языка вы можете использовать только шаблоны или макросы для метапрограммы. Средства метапрограммирования, предлагаемые, скажем, библиотекой Boost Preprocessor, которая реализует некоторые действительно удивительные вещи, такие как макросы, являются чрезвычайно мощными.

Однако, если вы хотите получить немного больше, вы можете использовать язык сценариев по вашему выбору для метапрограммы.

1 голос
/ 11 января 2011

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

Анализ существующих заголовочных файлов C ++ вместо этого является кошмаромиз-за сложного синтаксиса C ++ ... (и зачем ограничивать себя в том, что вы хотите выразить?).

Python является мультиплатформенным и очень хорошим языком как таковым ...

КакПример, приведенный ниже, является примером «расширенного» C ++, который я использовал ...

//
// U8 -> F32 format converter
//
//    - src(Image:U8) ............ source image
//    - dst(pImage:F32:src) ...... destination image
//
ImgFilter u8_to_f32(Image& src, Image& dst)
{
    const double k = 1.0/255;
    for (int y=0; y<src.h; y++)
    {
        unsigned char *rp = src.u8(0, y);
        float *wp = dst.f32(0, y);
        for (int x=0,w=src.w; x<w; x++)
            *wp++ = *rp++ * k;
    }
}

Комментарий над функцией и имя / параметры читаются скриптом python, который генерирует .h для функции,Код C ++, который обрабатывает распределение памяти, проверки размера и совместимости форматов, анализ аргументов командной строки, интерактивную справку и привязку к Python.По сути, я могу написать только «мясо» и получить весь шаблон для меня.Сценарий Python, выполняющий это, составляет 200 строк, и, учитывая количество сгенерированного кода, шаблон C ++ для пары фильтров уже больше, чем это.

0 голосов
/ 14 января 2011

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

Наш набор DMS Software Reengineering Toolkit является именно такой системой.Он параметризован явным описанием языка программирования, подлежащего обработке, и заданием, которое вы хотите выполнить в исходном коде.DMS уникальна в своем роде (Джекпот - это система преобразования программ только для Java) и вдвойне уникальна, имея надежный C ++ Front End , который использовался для крупномасштабных задач преобразования в производственной среде C ++.system.

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

...