Template metaprogramming (TMP, templating meta-programming) This is written template-based C + + planning. The compilation process. Template metaprogramming with C + + writing templates program, the process of processing. In other words, after the TMP program runs, the C + + source code is detailed from templates. is no longer a template.
TMP has two functions, one is that it makes something easier.
such as writing STL containers, using templates, but storing whatever type of element. The second is to transfer some of the work running during the run-time to the compile period. Another result is that C + + programs that use TMP may be more efficient in other ways: smaller, less-run files, shorter runs, and less memory requirements. However, the run-time work is transferred to the compile time. The compilation period may become longer.
Take a look at the advance pseudo code in clause 47
template<typenametypename DistT> void advance(IteT& iter,DistT d) { if(iter is a random access iterator) iter+=d; else { if(d>=0) while(d--) ++iter; else while(d++) --iter; } }
Ability to use typeID to infer the pseudo code of the ITER type to run
template <typename Iter, typename distt> void advance (itet& iter,distt D) {if (typeid (typename STD :: iterator_traits<itert>::iterator_category) ==typeid (std :: Random_access_iterator_tag)) Iter+=d; else {if (D>=0 ) while (d--) ++iter; else while (d++)--iter; } }
The efficiency of the typeid-based solution is lower than the traits solution, because in this scenario, the 1 type test occurs at run time rather than compile time, and the 2 run-time type test code is in (or is connected to) a running file.
This example demonstrates that TMP is more efficient than a normal C + + program because the traits solution is TMP.
Some things are easier in tmp than in normal C + +. Advance provides a good example.
Advance typeid-based implementations may cause compile-time issues
STD:: list<int>:: Iterator iter; ... advance (ITER,Ten);voidAdvanceSTD:: list<int>::iterator& ITER,intD) {if(typeID(TypeName STD::iterator_traits<STD:: list<int>:: iterator>::iterator_category) = =typeID(STD:: Random_access_iterator_tag)) Iter+=d;//Error Else{if(d>=0) while(d--) ++iter;Else while(d++)--iter; } }
Error is called on the + = operator. Because List::iterator does not support + =, it is an bidirectional iterator.
We know that we will not run the + = line because the typeID line is not always equal, but the compile time ensures that all the source code is valid, even if the code is not running. The traits-based TMP solution runs different codes for different types without the above problems.
TMP has been shown to be a Turing machine, which means it is powerful enough to calculate whatever it is. Ability to declare variables with TMP, run loops, write calling functions .... Sometimes this will look very different from normal C + + counterparts. For example, the TMP if-else shown in clause 47 is shown in detail by Templas and its specificity. But that is the assembly language level of TMP. Library for TMP design (e.g. Boost's MPL). * * clause **55) provides more advanced syntax.
To see how things work in TMP again, look at the loop. TMP does not have a true loop. The loop is completed by recursion (recursion).
TMP recursion is not even normal recursion. Because the TMP recursion does not involve recursive function calls, it involves recursive templating (recursive template instantiation).
The TMP's starting-up program calculates the factorial at compile time.
The factorial transport of TMP demonstrates how to implement loops through recursive template detailing and how to create and use variables in TMP
template<unsigned n> struct Factorial{ enum {value=n*Factorial<n-1>::value}; }; template<> struct Factorial<0//特殊情况。Factorial<0>的值是1 enum {value=1}; };
With this template metaprogram, the n factorial value can be obtained simply by referring to the Factorial::value. The loop occurs when the template details the factorial internal refers to another template detailing the factorial.
The special case of the template-specific version number factorial<0> is the end of the recursion.
Each of the factorial template details is a struct. Each struct declares a TMP variable with the name value, which is used to hold the factorial value obtained by the current calculation.
TMP replaces loops with recursive template details. Every detail has its own value, and each value has its own appropriate value within the loop.
Demonstrating TMP with factorial is like using the Hello World Model programming language. In order to understand that TMP is worth learning, it is necessary to have a better understanding of what it can achieve. Here are three examples:
typedef SquareMatrix<double,1000> BigMatrix; BigMatrix m1,m2,m3,m4,m5; …… BigMatrix result=m1 * m2 * m3 * m4 * m5;
The multiplication above produces four transient matrices, and multiplication may produce 4 loops that act on the elements of a matrix. Assuming the use of advanced, TMP-related template (that is, expression templates), it is possible to eliminate those temporary objects and merge loops. So TMP uses less memory. The speed of operation is also improved.
- Be able to generate custom design pattern implementations. Using policy-based Design's tmp-based technology, it is possible to produce some templates to express independent design items (so-called policies). They are then able to combine them at will, resulting in pattern fulfillment with customized behavior.
TMP is not fully mature at the moment, the grammar is not intuitive, the supporting tools are not enough.
However, TMP is very attractive for performance that is difficult or even impossible to achieve in the run-time. Although TMP will not become mainstream. But it will become the main food for some program apes (especially developers of libraries).
Summarize
- Template metaprogramming (TMP, templating meta-programming) moves the work from the runtime to the compile time, enabling early error detection and higher operational efficiency.
- TMP can be used to generate customer-specific code based on the policy selection combination (based on combinations of policy choices). It can also be used to avoid generating code that is not appropriate for certain special types.
Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.
"Effective C + +": Clause 48: Understanding template meta-programming