git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@392 f6dd340e-d3f9-0310-b409-bdd246841980
This commit is contained in:
Frank B. Brokken 2010-02-10 20:00:55 +00:00
parent dd701821d7
commit be726acf65
3 changed files with 38 additions and 39 deletions

View file

@ -22,13 +22,13 @@ sect(Template Meta Programming)
lsubsubsect(INTTYPE)(Converting integral types to types)
includefile(advancedtemplates/int2type)
COMMENT(>>>>>>>>>>>>> NEXT <<<<<<<<<<<<<)
lsubsect(ALTERNATIVES)(Selecting alternatives using templates)
includefile(advancedtemplates/alternatives)
subsect(Templates: Iterations by Recursion)
includefile(advancedtemplates/iterating)
COMMENT(>>>>>>>>>>>>> NEXT <<<<<<<<<<<<<)
lsect(TEMPTEMPPAR)(Template template parameters)
includefile(advancedtemplates/templateparam)

View file

@ -255,9 +255,7 @@ implementations of these overloaded members may then be optimized to the
various data types. In programs only one of these alternate functions (the one
that is optimized to the actually used data types) will then be instantiated.
COMMENT(>>>>>>>>>>>>> NEXT <<<<<<<<<<<<<)
Note that the overloaded tt(add) functions have identical parameter lists
as the matching public wrapper function, but add to this parameterlist a
specific tt(IntType) type, allowing the compiler to select the appropriate
overloaded version, based on the template's non-type selector parameter.
The private tt(add) functions define the same parameters as the public
tt(add) wrapper function, but add a specific tt(IntType) type, allowing the
compiler to select the appropriate overloaded version based on the template's
non-type selector parameter.

View file

@ -1,27 +1,25 @@
Since there are no variables
hi(templates: no variables)
in template meta programming, there is no way to implement iteration using
templates. However, iterations can always be rewritten as recursions, and
since recursions em(are) supported by templates iterations can always be
rewritten as (tail) recursions.
As there are no variables in template meta programming, there is no
template equivalent to a tt(for) or tt(while) statement. However, iterations
can always be rewritten as recursions. Recursions em(are) supported
by templates and so iterations can always be implemented as (tail) recursions.
hi(templates: iteration by recursion)
The principle to follow here is:
To implement iterations by (tail) recursion do as follows:
itemization(
it() Define a specialization implementing the end-condition;
it() Define all other steps using recursion.
it() Store intermediate values as tt(enum) values.
it() define a specialization implementing the end-condition;
it() define all other steps using recursion.
it() store intermediate values as tt(enum) values.
)
Since the compiler will select a more specialized implementation over a
more generic one, by the time it reaches the final recursion it will stop the
recursion since the specialization will not rely on recursion anymore.
The compiler selects a more specialized template implementation over a
more generic one. By the time the compiler reaches the end-condition the
recursion stops since the specialization does not use recursion.
Most readers will be familiar with the recursive implementation of the
mathematical `em(factorial)' operator, indicated by the exclamation mark
(tt(!)). Factorial tt(n) (so: tt(n!)) returns the successive products tt(n *
(n - 1) * (n - 2) * ... * 1), representing the number of ways tt(n) objects
can be permuted. Interestingly, the factorial operator is usually defined by a
em(recursive) definition:
mathematical `em(factorial)' operator, commonly represented by the exclamation
mark (tt(!)). Factorial tt(n) (so: tt(n!)) returns the successive products
tt(n * (n - 1) * (n - 2) * ... * 1), representing the number of ways tt(n)
objects can be permuted. Interestingly, the factorial operator is itself
usually defined by a em(recursive) definition:
verb(
n! = (n == 0) ?
1
@ -29,10 +27,10 @@ em(recursive) definition:
n * (n - 1)!
)
To compute tt(n!) from a template, a template tt(Factorial) can be defined
using a tt(int n) template non-type parameter, and defining a specialization
using an tt(int n) template non-type parameter. A specialization is defined
for the case tt(n == 0). The generic implementation uses recursion according
to the factorial definition. Furthermore, the tt(Factorial) template defines an
tt(enum) value `tt(value)' to contain the its factorial value. Here is the
to the factorial definition. Furthermore, the tt(Factorial) template defines
an tt(enum) value `tt(value)' containing its factorial value. Here is the
generic definition:
verb(
template <int n>
@ -41,17 +39,19 @@ generic definition:
enum { value = n * Factorial<n - 1>::value };
};
)
Note how the expression assigning a value to `tt(value)' uses constant,
compiler determinable values: n is provided, and tt(Factorial<n - 1>()) is
computed by em(template meta programming), also resulting in a compiler
determinable value. Also note the interpretation of tt(Factorial<n - 1>::value):
it is the tt(value) defined by the type tt(Factorial<n - 1>); it's em(not),
e.g., the value returned by an em(object) of that type. There are no objects
here, simply values defined by types.
Note how the expression assigning a value to `tt(value)' uses constant
values that can be determined by the compiler. The value n is provided, and
tt(Factorial<n - 1>) is computed using em(template meta
programming). tt(Factorial<n-1>) in turn results in value that can be
determined by the compiler (em(viz.)
tt(Factorial<n-1>::value)). tt(Factorial<n-1>::value) represents the tt(value)
defined by the em(type) tt(Factorial<n - 1>). It is em(not) the value returned
by an em(object) of that type. There are no objects here but merely values
defined by types.
To end the resrsion a specialization is required, which will be preferred
by the compiler over the generic implementation when its template arguments
are present. The specialization can be provided for the value 0:
The recursion ends in a specialization. The compiler will select the
specialization (provided for the terminating value 0) instead of the generic
implementation whenever possible. Here is the specialization's implementation:
verb(
template <>
struct Factorial<0>
@ -69,7 +69,8 @@ number of permutations of a fixed number of objects. E.g.,
}
)
Once again, tt(Factorial<5>::value) is em(not) evaluated run-time, but
compile-time. The above statement is therefore run-time equivalent to:
compile-time. The run-time equivalent of the above tt(cout) statement is,
therefore:
verb(
int main()
{