Метапрограммирование шаблона C ++ - возможно ли вывести сгенерированный код? - PullRequest
25 голосов
/ 02 августа 2009

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

Когда я пытаюсь вывести предварительно обработанные исходные файлы, я получаю 125 000 строк кода: /

Так есть ли способ увидеть сгенерированный код? (Я использую библиотеку SeqAn )

Ответы [ 5 ]

24 голосов
/ 02 августа 2009

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

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

Как только вы начнете теряться в метапрограммировании, этот простой трюк поможет вам определить, какой тип параметра шаблона на самом деле:

// given a variable t of an unknown type T
int*** i = t;

Когда с этим сталкивается компилятор, он выведет красивое и простое сообщение об ошибке «Не удается преобразовать <long, detailed typename> в int ***», что позволит вам легко убедиться, что параметр шаблона T действительно соответствует типу, который вы используете. думаю, что так и должно быть.

22 голосов
/ 02 августа 2009

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

14 голосов
/ 22 марта 2010

Проверка Моя публикация по отладке метапрограмм шаблона C ++

На странице 6 вы можете увидеть, как это работает. Для определенных целей вам не понадобится весь набор инструментов, это можно сделать вручную.

Я собрал надстройку Visual C ++, где вы могли бы размещать точки останова и т. Д., Но это было скорее доказательство концепции, чем инструмент для повседневного использования.

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

ОБНОВЛЕНИЕ: отладчик и профилировщик доступны здесь

ОБНОВЛЕНИЕ: C ++ Теперь презентация

5 голосов
/ 02 августа 2009

Это потенциально ответ на ваш вопрос:

C ++ Шаблон препроцессора инструмента

Кажется, что удовлетворил последнего человека, который спросил - хотя я не могу понять, почему Вывод компилятора C ++ в C, как правило, довольно нечитабелен, поскольку он не предназначен для помощи в понимании, а является лишь своего рода переносимым языком ассемблера.

1 голос
/ 02 августа 2009

вообще невозможно вывести весь код. Но что мне показалось чрезвычайно интересным, так это возможность использовать отладчик Visual C ++, чтобы показать вам тип. Возьмите эту простую метапрограмму:

template<class Head, class Tail>
struct type_list
{
  typedef Head head;
  typedef Tail tail;
};

struct null_type
{};

template<class List>
struct list_head
{
  typedef typename List::head head;
};

template<class List>
struct list_tail
{
  typedef typename List::tail tail;
};

template<class List>
struct list_length
{
  static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
};

template<>
struct list_length<null_type>
{
  static const size_t length = 0;
};


int main()
{
  typedef 
    type_list
    < int
    , type_list
      < double
      , type_list
        < char
        , null_type
        >
      >
    >       my_types;

  my_types test1;

  size_t length=list_length<my_types>::length;

  list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;

}

Я только что создал свои мета-типы. Это все еще пустые экземпляры класса C ++ длиной не менее 1 байта. Теперь я могу поставить точку останова после последнего создания test2 и посмотреть, какие типы / значения длины, test1 и test2 имеют:

Вот что показывает отладчик:

length  3   unsigned int
test1   {...}   type_list<int,type_list<double,type_list<char,null_type> > >
test2   -52 'Ì' char

Теперь вы знаете, что голова вернула вам символ, ваш список содержит int, double, char и заканчивается null_type.

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

Надеюсь, это поможет,
Ованес

...