Автоматически подсчитывать количество экземпляров классов в TMP?

учитывая метапрограмму шаблона (TMP), компиляторы C++ производят статистику сборки, которая подсчитывает количество экземпляров классов? Или есть другой способ автоматически получить этот номер? Так, например, для obiquitous factorial

#include <iostream>

template<int N> struct fact { enum { value = N * fact<N-1>::value }; };
template<> struct fact<1> { enum { value = 1 }; };

int main()
{
    const int x = fact<3>::value;
    std::cout << x << "n";
    return 0;
}

Я хотел бы вернуть число 3 (поскольку экземпляр fact, fact и fact). Этот пример, конечно, тривиален, но всякий раз, когда вы начинаете использовать, например, Boost.MPL, время компиляции действительно взрывается, и я хотел бы знать, сколько это связано с скрытыми экземплярами классов. Мой вопрос в первую очередь для Visual C++, но ответы для gcc также будут оценены.

редактировать: мой текущий очень хрупкий подход для Visual C++ добавляет переключатель компиляции из одного из Stephan T. Lavavej видео /d1reportAllClassLayout и выполнение подсчета grep + word в выходном файле, но это (a) увеличивает время компиляции чрезвычайно и (b) регулярное выражение трудно получить 100% правильно.

3 ответов


Я в одну строку изменить в GCC, что делает его распечатать имя каждого шаблона класса, как он создает его. Вы уже можете вызвать интерфейс C++cc1plus без -quiet флаг, чтобы сделать то же самое для шаблонов функций.

у меня еще нет времени превращать это в правильный вариант GCC, это просто Хак на моем собственном дереве источников. Я думаю реализовать его как плагин, но он не находится в верхней части моего списка задач.


конечно, нет портативного способа сделать это.

есть хакерские способы сделать это для большинства компиляторов. Вы уже нашли один для MSVC. Для gcc, вероятно, можно использовать gccxml. Или для любого компилятора с открытым исходным кодом (gcc или clang) должно быть довольно просто добавить код в момент создания экземпляра, который либо ведет счет, либо регистрирует что-то, что вы можете фильтровать после компиляции.

для Clang / LLVM вы можете просто создать плагин, который подключает экземпляр, что намного чище, но, вероятно, на самом деле больше работы.

сборка с символами отладки, без оптимизации и без зачистки может закончиться искаженными именами каждого экземпляра, для которого вы можете grep. Однако некоторые компиляторы (включая gcc) всегда будут встроены по крайней мере в некоторые методы, хотите вы этого или нет. Если вы хотите изменить свой код, вы, вероятно, можете заставить его генерировать устаревшие экземпляры, возможно, что-то вроде этого:

template<int N> struct fact { 
  enum { value = N * fact<N-1>::value }; 
  int *dummy() { return &fact<N-1>::value; }
};

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