Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
258 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...