3

Now, I'm familiar with templates and I'm somewhat familiar with things like SFINAE, and I've been wondering what goes on when a template is instantiated by the compiler.

When you do things in TMP, like SFINAE, or even the simple Fibonacci sequence in TMP, it seems like the compiler is doing more than what I understand under template instantiation. It seems the compiler is executing the template code.

My question is, what exactly is template instantiation and where is the line drawn with the compiler actually executing code?

The compiler creates a type of your template, is my understanding of template instantiation. But in TMP it seems like it's doing a whole lot more than that, and that confuses me.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • 1
    One way to better understand the way C++ templates can be used to perform calculations at runtime is to learn the basics of Prolog: template meta-programming borrows heavily from the programming style typical of Prolog. – Sergey Kalinichenko May 09 '12 at 01:08
  • 1
    It most assuredly does not have anything to do with PROLOG. It is a functional style more reminiscent of Haskell. – Puppy May 09 '12 at 01:14
  • @dasblinkenlight Could you elaborate? I've tried Prolog before and it reminds me nothing of it. I don't think Haskell is a great comparison as TMP lacks a type system. – Pubby May 09 '12 at 01:21
  • @Pubby: It's reminiscent. Not identical or even similar. However there are many places showing where you can emulate Haskell code using TMP. – Puppy May 09 '12 at 01:25
  • @Pubby Take a look at Prolog's [list processing](http://www.ling.helsinki.fi/kit/2003k/ctl272/Bangor/clbook_22.html#1) - it is a very common pattern in Prolog to specify recursive step in a separate rule from the termination condition. Template metaprogramming uses the same pattern: there is a template that provides a step, and an explicit instantiation that provides a termination condition. – Sergey Kalinichenko May 09 '12 at 01:37
  • @dasblinkenlight: It's a common pattern in any language which is not imperative, including all of the functional ones. TMP bears a much stronger resemblance to them than the disgusting cesspit of PROLOG. – Puppy May 10 '12 at 13:44

1 Answers1

3

It's best to think of it as a bunch of functions, which is what it really is. Consider a class Type, which here represents the compiler's internal representation of a type.

template<typename T> class X {
    T t;
};

In run-time C++, you could express this as

Type* X(Type *t) {
    static std::unordered_map<Type*, Type*> cache;
    if (cache.find(t) != cache.end())
        return cache[t];
    Type* ret = new Type;
    ret->DataMembers.insert("t", t);
    return cache[t] = ret;
}

Of course, a little extra would be needed for specializations and such. Using this model, though, it's easy to two things.

A) Instantiating a template is equivalent to a function call, which happens to occur at compile-time, just like constexpr. Of course, a clever compiler may do something else as an optimization, but in the general case.

B) How it extends to any other functionality provided by templates.

Because instantiating a template is Turing-complete, you can't really handle it any other way. The reason it seems like the compiler is executing them is because it is. They are nothing more than functions in a limited EDSL with bad syntax.

Puppy
  • 144,682
  • 38
  • 256
  • 465