Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compile time loops

Tags:

c++

templates

I would like to know if it is possible to have sort of compile time loops.
For example, I have the following templated class:

template<class C, int T=10, int B=10> class CountSketch { public:     CountSketch()     {             hashfuncs[0] = &CountSketch<C>::hash<0>;          hashfuncs[1] = &CountSketch<C>::hash<1>;          // ... for all i until i==T which is known at compile time     }; private:     template<int offset>     size_t hash(C &c)     {         return (reinterpret_cast<int>(&c)+offset)%B;     }     size_t (CountSketch::*hashfuncs[T])(C &c); }; 

I would thus like to know if I can do a loop to initialize the T hash functions using a loop. The bounds of the loops are known at compile time, so, in principle, I don't see any reason why it couldn't be done (especially since it works if I unroll the loop manually).

Of course, in this specific example, I could just have made a single hash function with 2 parameters (although it would be less efficient I guess). I am thus not interested in solving this specific problem, but rather knowing if "compile time loops" existed for similar cases.

Thanks!

like image 786
nbonneel Avatar asked Jul 29 '11 12:07

nbonneel


People also ask

Are loops evaluated at compile-time?

In general, for loops can't be compile -time evaluated.

Are templates compile-time or runtime?

All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!

Why is compile-time important?

If we have to wait for the compilation part, that slows down the entire workflow. And time is money. If one manages to optimise the compilation time down to a few milliseconds, then we can move on to testing our changes. If we need to wait hours until that step, that creates a bottleneck in the development.

What is compile-time in CPP?

A compile-time constant is a value that is computed at the compilation-time. Whereas, A runtime constant is a value that is computed only at the time when the program is running. 2. A compile-time constant will have the same value each time when the source code is run.


1 Answers

Nope, it's not directly possible. Template metaprogramming is a pure functional language. Every value or type defined through it are immutable. A loop inherently requires mutable variables (Repeatedly test some condition until X happens, then exit the loop).

Instead, you would typically rely on recursion. (Instantiate this template with a different template parameter each time, until you reach some terminating condition).

However, that can solve all the same problems as a loop could.

Edit: Here's a quick example, computing the factorial of N using recursion at compile-time:

template <int N> struct fac {   enum { value = N * fac<N-1>::value }; };  template <> struct fac<0> {   enum { value = 1 }; };  int main() {   assert(fac<4>::value == 24); } 

Template metaprogramming in C++ is a Turing-complete language, so as long as you don't run into various internal compiler limits, you can solve basically any problem with it.

However, for practical purposes, it may be worth investigating libraries like Boost.MPL, which contains a large number of data structures and algorithms which simplify a lot of metaprogramming tasks.

like image 130
jalf Avatar answered Oct 04 '22 06:10

jalf