Use the C ++ template meta-programming template to "sum during compilation" the Array"

Source: Internet
Author: User

Evaluate during compilation and advance computation to compilation to maximize the potential of the compiler and improve the program running speed, in the words of Andrei Alexander erescu, "time is spent in the compilation phase. In a sense, this is 'free'" ("C ++ new design thinking" p55 ). Therefore, we need to sum the arrays during compilation.

First go to the code and then explain:

# Include <iostream> using namespace STD; // a global int array, which must be summed to const int const_array [5] = {, 5 }; // after removing the const attribute, you can also compile a class template to sum the array using the template <int index> struct sumarrincompilephasecls {static const int sum ;}; // recursively define the template to obtain the sum value template <int index> const int sumarrincompilephasecls <index >:: sum = const_array [Index] + sumarrincompilephasecls <index-1> :: SUM; // highlights here // a fully-specific class template, used to end the template's recursive definition template <> struct sumarrincompilephasecls <0 >{ static const int sum ;}; const int sumarrincompilephasecls <0>: Sum = const_array [0]; int main () {// use the template to sum the arrays during compilation. <sumarrincompilephasecls <4> :: sum <Endl; // result 15}

Sum is indeed calculated in the compilation phase. Because sum is of the static const type, this type is fixed after compilation and cannot be changed during runtime!

After carefully studying the code above, we will find that the recursive definition of the template is used when defining the sum value of the non-specific class template:

// Recursively define the template to obtain the sum value template <int index> const int sumarrincompilephasecls <index >:: sum = const_array [Index] + sumarrincompilephasecls <index-1> :: SUM;

When the compiler compiles this expression, because the sumarrincompilephasecls <index-1> type is unknown, the compiler generates the sumarrincompilephasecls <index-1> and generates the sumarrincompilephasecls <index-2>, sumarrincompilephasecls <index-3> ,...... There are many more ~. That is to say, this expression causes the compiler to recursively generate multiple sumarrincompilephasecls template classes. When the index is finally reduced to 0, it is necessary to generate sumarrincompilephasecls <0>, sumarrincompilephasecls <0> has been implemented! So the compiler stops generating the "sumarrincompilephasecls Template Class" and the recursion is over!

Since the sum values in all "sumarrincompilephasecls template classes" are static const values, you can sum the const values during compilation.

Is it over?

Yes!

The above code has two minor issues:

1. If the input index is negative (for example,-1) During the call, recursive stack overflow occurs during compilation and compilation fails! Because the negative number cannot be "reduced to 0", that is, recursion will not stop!

2. The input index exceeds the upper limit of const_array (for example, 5). Although the index is compiled successfully, the running result is incorrect because the array exceeded during the sum process!

Now, when we want to sum the array, we can determine whether the user input is legal!

You can add an "asserted during compilation" to solve these two problems. The source code of this asserted is as follows:

// A class template that acts as an assertion during compilation to ensure that the array subscript is always non-negative. <bool isok> struct compilephaseassertion; Template <> struct compilephaseassertion <true> {};

This can be used as follows:

// A class template used to sum the array. template <int index> struct sumarrincompilephasecls {static const int sum; private: compilephaseassertion <index> = 0 & index <sizeof (const_array) /sizeof (INT)> isvalidindex ;};

The principle is obvious, right?

Compilephaseassertion is a class template, but it is not defined! There is only one fully-specific version with the parameter true. Therefore, when the isok parameter of the template is false, instances of this type cannot be generated because there is no template class with isok = false, therefore, an error occurs during compilation.

By adding a compilephaseassertion instance to compilephaseassertion, the index range is valid.

The modified code is as follows:

# Include <iostream> using namespace STD; // a global int array, which requires the sum of int const_array [5] = {1, 2, 4, 5 }; // a class template that acts as an assertion during compilation to ensure that the array subscript is always non-negative. <bool isok> struct compilephaseassertion; Template <> struct compilephaseassertion <true> {}; // a class template used to sum the array. template <int index> struct sumarrincompilephasecls {static const int sum; private: compilephaseassertion <index> = 0 & index <sizeof (const_array) /sizeof (INT)> isvalidindex;}; // You Can recursively define a template to obtain the sum value. template <int index> const int sumarrincompilephasecls <index> :: sum = const_array [Index] + sumarrincompilephasecls <index-1>: sum; // a fully-specialized class template, recursive template used to end the template <> struct sumarrincompilephasecls <0> {static const int sum ;}; const int sumarrincompilephasecls <0 >:: sum = const_array [0]; int main () {// use the template to sum the arrays during compilation. cout <sumarrincompilephasecls <4 >:: sum <Endl ;}

In this case, if the following two methods are used for summation, an error is reported during compilation:

Cout <sumarrincompilephasecls <-1>: Sum <Endl; // The array subscript is negative cout <sumarrincompilephasecls <5>: Sum <Endl; // the upper limit of the array is out of bounds.

The text is complete.

References:

1. New Thinking in C ++ design, translated by Andrei Alexander erescu, Hou Jie, and Yu chunjing.

2. c ++ template metaprogramming Technology and Application

3. Other articles or books written by Mr. Roewe

4. Introduction to metaprogramming in C ++

Note:

The above code can be compiled in vs2005 and G ++, but only the program compiled by G ++ can run the correct result (15 ), the result in vs2005 is incorrect (5). The cause is unclear. If you know the cause of the vs2005 calculation error, please leave a message to inform me. I will be very grateful to you!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.