The nature of template
meta-programming
Template
meta-programming is much closer to functional programming than ordinary
idiomatic C++ is. This is because 'variables' are all immutable, and hence it
is necessary to use recursion rather than iteration to process elements of a
set. This adds another layer of challenge for C++ programmers learning TMP: as
well as learning the mechanics of it, they must learn to think in a different
way.
Limitations of Template Meta-programming
Because
template meta-programming evolved from an unintended use of the template
system, it is frequently cumbersome. Often it is very hard to make the intent
of the code clear to a maintainer, since the natural meaning of the code being
used is very different from the purpose to which it is being put. The most
effective way to deal with this is through reliance on idiom; if you want to be
a productive template meta-programmer you will have to learn to recognize the
common idioms.
It also
challenges the capabilities of older compilers; generally speaking, compilers
from around the year 2000 and later are able to deal with much practical TMP code.
Even when the compiler supports it, the compile times can be extremely large
and in the case of a compile failure the error messages are frequently
impenetrable.
Some
coding standards may even forbid template meta-programming, at least outside of
third-party libraries like Boost.
History
of TMP
Historically
TMP is something of an accident; it was discovered during the process of
standardizing the C++ language that its template system happens to be
Turing-complete, i.e., capable in principle of computing anything that is
computable. The first concrete demonstration of this was a program written by
Erwin Unruh which computed prime numbers although it did not actually finish
compiling: the list of prime numbers was part of an error message generated by
the compiler on attempting to compile the code.[1] TMP has since advanced
considerably, and is now a practical tool for library builders in C++, though
its complexities mean that it is not generally appropriate for the majority of
applications or systems programming contexts.
#include
<iostream>
template
<int p, int i>
class
is_prime { public:
enum {
prim = ( (p % i) && is_prime<p, i - 1>::prim ) };
};
template
<int p>
class
is_prime<p, 1>
{
public:
enum {
prim = 1 };
};
template
<int i>
class Prime_print
{ // primary template for loop to print prime numbers public:
Prime_print<i
- 1> a;
enum {
prim = is_prime<i, i - 1>::prim }; void f() {
a.f();
if (prim)
{
std::cout
<< "prime number:" << i << std::endl;
}
}
};
template<>
class
Prime_print<1> { // full specialization to end the loop public:
enum {
prim = 0 }; void f() {}
};
#ifndef
LAST
#define
LAST 18
#endif
int
main()
{
Prime_print<LAST>
a; a.f();
}
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.