пример
#include <iostream>
template <int N> struct Factorial
{
enum { val = Factorial<N-1>::val * N };
};
template<>
struct Factorial<0>
{
enum { val = 1 };
};
int main()
{
// Note this value is generated at compile time.
// Also note that most compilers have a limit on the depth of the recursion available.
std::cout << Factorial<4>::val << "\n";
}
Это было немного весело, но не очень практично.
Чтобы ответить на вторую часть вопроса:
полезен ли этот факт на практике?
Краткий ответ: вроде как.
Длинный ответ: Да, но только если вы демон шаблона.
Наладить хорошее программирование с использованием шаблонного метапрограммирования, действительно полезного для других (например, библиотеки), действительно сложно (хотя и выполнимо). Чтобы помочь бусту, даже есть MPL (библиотека мета-программирования). Но попробуйте отладить ошибку компилятора в коде шаблона, и вас ждет долгая тяжелая поездка.
Но хороший практический пример его использования для чего-то полезного:
Скотт Мейерс работал над расширениями языка C ++ (я использую этот термин вольно), используя средства создания шаблонов. Вы можете прочитать о его работе здесь « Применение функций кода ».
Я сделал машину Тьюринга на C ++ 11. Возможности, добавленные в C ++ 11, действительно не имеют значения для машины Тьюринга. Он просто предоставляет списки правил произвольной длины с использованием вариативных шаблонов вместо использования извращенного метапрограммирования макросов :). Имена условий используются для вывода диаграммы на стандартный вывод. я удалил этот код, чтобы образец был коротким.
источник
" Шаблоны C ++ завершены по Тьюрингу " дает реализацию машины Тьюринга в шаблонах ... что нетривиально и прямо доказывает суть дела. Конечно, это тоже не очень полезно!
источник
Мой C ++ немного ржавый, так что он может быть не идеальным, но близок.
Дело в том, чтобы продемонстрировать, что компилятор полностью оценивает рекурсивное определение, пока не достигнет ответа.
источник
Приведу нетривиальный пример: http://gitorious.org/metatrace , трассировщик лучей времени компиляции C ++.
Обратите внимание, что C ++ 0x добавит нешаблонное, время компиляции, средство по Тьюрингу в форме
constexpr
:Вы можете использовать
constexpr
-expression везде, где вам нужны константы времени компиляции, но вы также можете вызватьconstexpr
-функции с неконстантными параметрами.Одна интересная вещь заключается в том, что это, наконец, позволит использовать математику с плавающей запятой во время компиляции, хотя в стандарте явно указано, что арифметика с плавающей запятой времени компиляции не должна соответствовать арифметике с плавающей запятой во время выполнения:
источник
Книга Андрея Александреску « Современный дизайн C ++ - универсальное программирование и шаблоны проектирования » - лучшее место, где можно познакомиться с полезными и мощными универсальными шаблонами программирования.
источник
Факторный пример на самом деле не показывает, что шаблоны являются полными по Тьюрингу, в большей степени он показывает, что они поддерживают примитивную рекурсию. Самый простой способ показать, что шаблоны являются полными по Тьюрингу, - это использовать тезис Черча-Тьюринга, то есть реализовать либо машину Тьюринга (беспорядочно и немного бессмысленно), либо три правила (app, abs var) нетипизированного лямбда-исчисления. Последнее намного проще и интереснее.
То, что обсуждается, является чрезвычайно полезной функцией, если вы понимаете, что шаблоны C ++ допускают чисто функциональное программирование во время компиляции, формализм, который является выразительным, мощным и элегантным, но также очень сложным для написания, если у вас мало опыта. Также обратите внимание, как многие люди считают, что получение сильно шаблонного кода часто требует больших усилий: это как раз тот случай, когда речь идет о (чистых) функциональных языках, которые усложняют компиляцию, но на удивление дают код, который не требует отладки.
источник
Я думаю, это называется метапрограммированием шаблонов .
источник
Что ж, вот реализация машины Тьюринга на этапе компиляции, в которой запущен двухсимвольный бобер с 4 состояниями.
Пробный прогон Ideone: https://ideone.com/MvBU3Z
Пояснение: http://victorkomarov.blogspot.ru/2016/03/compile-time-turing-machine.html
Github с дополнительными примерами: https://github.com/fnz/CTTM
источник
Вы можете проверить эту статью доктора Доббса о реализации БПФ с шаблонами, что, на мой взгляд, не так уж и тривиально. Главное - позволить компилятору выполнить лучшую оптимизацию, чем для реализаций без шаблона, поскольку алгоритм БПФ использует множество констант (например, таблицы sin).
часть I
Часть II
источник
Также интересно отметить, что это чисто функциональный язык, хотя его практически невозможно отладить. Если вы посмотрите на сообщение Джеймса, вы увидите, что я имею в виду под его функциональностью. В общем, это не самая полезная функция C ++. Он не был предназначен для этого. Это то, что было обнаружено.
источник
Это может быть полезно, если вы хотите вычислять константы во время компиляции, по крайней мере, теоретически. Ознакомьтесь с метапрограммированием шаблонов .
источник
Пример, который достаточно полезен, - это класс отношения. Есть несколько вариантов. Уловить случай D == 0 довольно просто с частичными перегрузками. Настоящие вычисления заключаются в вычислении GCD N и D и времени компиляции. Это важно, когда вы используете эти отношения при вычислениях во время компиляции.
Пример: когда вы вычисляете сантиметры (5) * километры (5), во время компиляции вы умножаете отношение <1,100> на отношение <1000,1>. Чтобы предотвратить переполнение, вам нужно соотношение <10,1> вместо отношения <1000,100>.
источник
Машина Тьюринга Тьюринг-полной, но это не значит , что вы должны использовать одну для производства кода.
По моему опыту, пытаться делать что-нибудь нетривиальное с помощью шаблонов беспорядочно, некрасиво и бессмысленно. У вас нет возможности «отлаживать» свой «код», сообщения об ошибках во время компиляции будут загадочными и обычно в самых маловероятных местах, и вы можете добиться тех же преимуществ в производительности разными способами. (Подсказка: 4! = 24). Хуже того, ваш код непонятен среднему программисту на C ++ и, вероятно, будет непереносимым из-за широкого диапазона уровней поддержки в текущих компиляторах.
Шаблоны отлично подходят для генерации общего кода (классы-контейнеры, оболочки классов, микшеры), но нет - на мой взгляд, полнота шаблонов по Тьюрингу НЕ ПОЛЕЗНА на практике.
источник
Еще один пример того, как не программировать:
Шаблоны публикации на C ++ завершены
источник
K17<Depth+1>::x * 5
.