Подорожуй з gofrie.com

Template Metaprogramming in C++

Практична користь шаблонів в плюсах — не тільки генерація коду (яскравий приклад — стратегії Alexandrescu), але й обчислення на етапі компіляції і оптимізація коду (далі поясню, що маю на увазі).

1. Обчислення на етапі компіляції. Представляють скоріше теоретичний інтерес, хоча і дають простір для оптимізації (в деяких практичних застосуваннях, наприклад, FFT, забезпечують дуже пристойний виграш в швидкості).
На жаль, чомусь всі люблять демонструвати паршиві приклади з неефективними алгоритмами (наприклад, числа Фібоначчі і піднесення до степеня ніколи не роблять правильно). Виправив цю досадну несправедливість.
Починаючи з C++11, такі трюки втрачають актуальність через constexpr, який дозволяє робити те саме, тільки зрозуміліше і естетичніше.

2. Оптимізація коду. Як правило, йдеться про якийсь ітеративний алгоритм, реалізовиний рекурсивними шаблонними визначеннями. Розумний компілятор, який знає трюки типу inlining і loop unrolling, може перетворити таку шаблонну рекурсивну функцію в звичайну послідовність операторів без логіки циклу чи рекурсії, тим самим значно вкоротивши кількість інструкцій.
Для прикладу, так можна перетворити BubbleSort масиву, розмір якого — стала етапу компіляції, в послідовність свопів, більше того, в цій ситуації prefetcher дасть максимальний приріст швидкості. Інший приклад — обчислення функції за розкладом в ряд Тейлора, кількість членів розкладу якого — теж константа етапу компіляції: на виході — код без зайвих змінних/лічильників/викликів функцій.

Проект для студії (версія 2013+) лежить тут. Деякі фічі типу static_assert не працюватимуть в старих студіях, їх можна закоментувати. З іншими компіляторами проблем бути не повинно (хіба якісь нюанси часткової спеціалізації).

А тут непогана презентація про шаблони в плюсах, в тому числі і про їх повноту за Тюрингом.

Enjoy!

Метапрограмування

Приклади :


template<int n>
struct Fib
{ enum { RET=Fib<n-1>::RET + Fib<n-2>::RET };
};
template <>
struct Fib<0>
{ enum { RET=0 };
};
template<>
struct Fib<1>
{ enum {RET=1};
};

cout << Fib<8>::RET << endl;

template<int n>
inline int power(const int& m)
{ return power<n-1>(m)*m;}
template<>
inline int power<1>(const int& m)
{ return m;}
template<>
inline int power<0>(const int& m)
{ return 1;}
cout << power<3>(m)<<endl;


template<bool condition, class Then, class Else>
struct IF
{ typedef Then RET;
};

template<class Then, class Else>
struct IF<false,Then,Else>
{ typedef Else RET;
};

IF<(1+2>4), short, int>::RET i;
//і має тип int

David Abrahams, Aleksey Gurtovoy. C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond



«C++ Template Metaprogramming» sheds light on the most powerful idioms of today's C++, at long last delivering practical metaprogramming tools and techniques into the hands of the everyday programmer.
Since the introduction of templates, C++ programmers have discovered surprising and powerful ways to perform computation at compile-time. While the excitement generated by these capabilities among C++ experts has reached the community at large, their practical application remains out-of-reach for many programmers. Literature on C++ template metaprogramming has focused primarily on details of low-level «tricks» at the expense of strong idioms and abstractions, and without illuminating the path from metaprogramming to expressive interfaces and efficient, maintainable software.

This book delivers both «big picture» ideas and practical tools. It explains what metaprogramming is, why it matters, and how the unique combination of features in C++ make it an especially powerful language for metaprogramming. It also presents the Boost Metaprogramming Library, a powerful open source framework of high-level compile-time components based on familiar STL idioms, which makes C++ metaprogramming easy, expressive, and fun.