Какие самые крутые примеры метапрограммирования вы видели в C++?[закрыто]

StackOverflow https://stackoverflow.com/questions/237425

Вопрос

Какие самые крутые примеры метапрограммирования вы видели в C++?
Какие практические применения метапрограммирования вы видели в C++?

Это было полезно?

Решение

Лично я думаю, что Boost.Spirit - довольно удивительный пример метапрограммирования. Это полный генератор синтаксического анализатора, который позволяет вам выражать грамматику с использованием синтаксиса C ++.

Другие советы

Наиболее практичное использование метапрограммирования - превращение ошибки времени выполнения в ошибку времени компиляции.

Пример. Позволяет вызвать интерфейс IFoo. Одна из моих программ имела дело с COM-объектом, который имел несколько путей к IFoo (очень сложная иерархия наследования). К сожалению, базовая реализация COM-объекта не осознавала, что у них есть несколько путей к IFoo. Они предполагали, что это всегда был самый левый. Таким образом, в их коде следующий шаблон был очень распространен

   void SomeMethod(IFoo* pFoo) {
        CFooImpl *p = (CFooImpl)pFoo;
   }

Второй IFoo вызвал результирующее " p " указатель должен быть полностью недействительным (множественное наследование опасно).

Долгосрочным решением было помочь владельцу COM-объекта решить эту проблему. Краткосрочный, хотя мне нужно было убедиться, что я всегда возвращал правильный IFoo. Я мог гарантировать, что у меня был соответствующий IFoo, используя QI и избегая любых неявных приведений к IFoo. Поэтому я создал новый CComPtr & Lt; & Gt; реализации и добавил следующее переопределение к методу равенства.

template <typename T>
CComPtr<T>& operator=(const T* pT)  { 
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
  COMPILE_ERROR();
}

Это быстро выявило все места, которые я неявно использовал в IFoo.

Не для практического использования (за исключением, может быть, для тестирования компилятора), но metatrace - это стиль Whited-стиля (то есть рекурсивный и детерминированный) трассировщик лучей, который генерирует изображения, подобные изображениям во время компиляции:

пример metatrace

Некоторые более сложные части кода можно увидеть в fixp.hh , в котором есть реализация sqrt с фиксированной точкой с использованием Heron метод или phere.hh , который показывает пересечение луча / сферы расчет.

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

Самый классный пример метапрограммирования: обманом компилятора для вычисления списка простых чисел. Не очень практично, но впечатляет.

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

Я должен был бы сказать Boost.Lambda, Boost.Function и Boost.Bind и то, как все они работают без сбоев. Они обеспечивают действительно удобный интерфейс и делают функциональное программирование максимально простым на языке, который для него не был создан.

luabind — довольно крутой практический пример, довольно хороший dsl для привязки классов C++ к lua.

BOOST_FOREACH

Статическое утверждение (повышает версию здесь )

(Примечание: встроенная поддержка циклов и статических утверждений на основе диапазона введена в C ++ 11)

Недавно я задал вопрос: C ++ Знание классов во время выполнения и ответ, который я получил от пользователя StackOverflow & Quot; Denice & Quot; был URL-адресом веб-сайта Meatspace: среда выполнения C ++ регистрация класса .

Я думаю, что это действительно крутой способ использовать шаблоны и создавать экземпляры объектов, которые являются производными от базового класса, так что, когда у меня есть 10 файлов C ++, они все могут просто добавить AUTO_REGISTER_BASE () внизу, и когда все сделано и связано, только те классы / файлы, которые его сделали, будут зарегистрированы, поэтому во время выполнения вы можете переключаться между различными классами, которые доступны, а те, которые недоступны, не зарегистрированы и, следовательно, не могут быть вызваны случайно .

Существует много различных зависящих от ОС способов уведомления о событиях (select (), kqueue (), / dev / epoll, у Solaris есть своя вещь, poll ()), и мне нужен был способ, чтобы все классы файлы существуют в каталоге, но в зависимости от того, с какой ОС был запущен Makefile, он будет компилировать только определенные. Мне нужен был способ узнать во время выполнения, какие из них были доступны, и чтобы программист мог использовать библиотеку для выбора своих предпочтений, однако, если было невозможно просто использовать тот, который имел наиболее логичный смысл для платформы (каждый из них им присвоены веса).

Приведенный выше код помог мне достичь этой цели, внеся ряд значительных изменений, но, тем не менее, помог мне!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top