Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create and initialize an array of values using template metaprogramming?

I want to be able to create an array of calculated values (let's say for simplicity's sake that I want each value to be the square of it's index) at compile time using template metaprogramming. Is this possible? How does each location in the array get initialized?

(Yes, there are easier ways to do this without resorting to template metaprogramming, just wondering if it's possible to do this with an array.)

like image 309
aneccodeal Avatar asked Feb 09 '10 02:02

aneccodeal


People also ask

What is template metaprogramming used for?

Template metaprogramming (TMP) is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled.

What is templating in programming?

A template is a C++ programming feature that permits function and class operations with generic types, which allows functionality with different data types without rewriting entire code blocks for each type.

What is TMP in C++?

Template meta-programming (TMP) refers to uses of the C++ template system to perform computation at compile-time within the code. It can, for the most part, be considered to be "programming with types" — in that, largely, the "values" that TMP works with are specific C++ types.

What do you mean by compile-time initialization give suitable example of compile-time initialization of C array?

Arrays can be initialized at the time they are declared. This is also known as compile-time initialization. We can initialize the elements of arrays in the same way as the ordinary variables when they are declared. The general form or syntax of initialization of arrays is: type array-name[size]={list of values};


2 Answers

It is possible in c++0x using variadic templates. Here is example how to create a table of binomial coefficients:

//typedefs used typedef short int              index_t; typedef unsigned long long int int_t;  //standard recursive template for coefficient values, used as generator template <index_t n, index_t k> struct coeff {static int_t const value = coeff<n-1, k-1>::value + coeff<n-1, k>::value;}; template <index_t n>            struct coeff<n, 0> {static int_t const value = 1;}; template <index_t n>            struct coeff<n, n> {static int_t const value = 1;};  //helper template, just converts its variadic arguments to array initializer list template<int_t... values> struct int_ary {static int_t const value[sizeof...(values)];}; template<int_t... values> int_t const int_ary<values...>::value[] = {values...};  //decrement k, pile up variadic argument list using generator template<index_t n, index_t k, int_t... values> struct rec: rec<n, k-1, coeff<n, k-1>::value, values...> {}; //when done (k == 0), derive from int_ary template<index_t n,            int_t... values> struct rec<n, 0, values...>: int_ary<values...> {};  //initialise recursion template<index_t n> struct binomial: rec<n, n+1> {}; 

To access elements use syntax like binomial<N>::value[k], where N is compile time constant and k is index ranging from 0 to N inclusive.

like image 57
qwe Avatar answered Sep 21 '22 21:09

qwe


It's called Static Table Generation in metaprogramming.

#include <iostream>  const int ARRAY_SIZE = 5;  template <int N, int I=N-1> class Table : public Table<N, I-1> { public:     static const int dummy; };  template <int N> class Table<N, 0> { public:     static const int dummy;     static int array[N]; };  template <int N, int I> const int Table<N, I>::dummy = Table<N, 0>::array[I] = I*I + 0*Table<N, I-1>::dummy;  template <int N> int Table<N, 0>::array[N];  template class Table<ARRAY_SIZE>;  int main(int, char**) {     const int *compilerFilledArray = Table<ARRAY_SIZE>::array;     for (int i=0; i < ARRAY_SIZE; ++i)         std::cout<<compilerFilledArray[i]<<std::endl; } 

We use explicit template instantiation and a dummy variable to force the compiler to fill the array with index squares. The part after I*I is the trick needed to recursively assign each array elements.

like image 39
David Lin Avatar answered Sep 21 '22 21:09

David Lin