4

I recently stumbled upon code that looks like this and I can't wrap my head around it:

template<typename T>
class A
{
}

class B: A<B>
{
}

So my general questions are:

  • Why does this not give a compile error? Specifically how can class B inherit from the template class A<B>, if B hasn't even been defined yet?
  • When would this structure ever be necessary?
Lawrence Aiello
  • 4,560
  • 5
  • 21
  • 35
flakes
  • 21,558
  • 8
  • 41
  • 88
  • 4
    C++ doesn't use a one-pass compiler. Referring to things that have been defined further down in the code is perfectly legal. – Robert Harvey Nov 05 '14 at 17:06
  • 4
    This is known as the "Curiously Recurring Template Pattern". – RichieHindle Nov 05 '14 at 17:07
  • 3
    http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – Remy Lebeau Nov 05 '14 at 17:07
  • @Remy Lebeau Thanks! Looks like some interesting reading material! – flakes Nov 05 '14 at 17:16
  • 1
    _"Why does this not give a compile error?"_ A template argument is not required to be a complete type, unless the template uses the argument in a way which would require it to be a complete type at the point of instantiation. – Oktalist Nov 05 '14 at 18:56

1 Answers1

3

One of the features: this template pattern can help you to avoid vtable usage. This called "Static polymorphism" - http://en.m.wikipedia.org/wiki/Curiously_recurring_template_pattern

Suppose you have this code structure:

class Item {
public:
    virtual void func() = 0;
}

class A : public Item {
// …
}

class B : public Item {
// …
}

Item *item = new A();
item->func();

It can be replaced with this:

template<typename T>
class Item {
public:
    void func() {
        T::func();
    }
}

class A : public Item<A> {
// …
}

class B : public Item<B> {
// …
}

Item<A> *item = new A();
item->func();

This way you can avoid virtual function call. This can be done for some performance improvement...

k06a
  • 17,755
  • 10
  • 70
  • 110
  • But why would you need a virtual call at all now that `A` objects cant be grouped with `B` objects by casting them as `Item` pointers? – flakes Nov 05 '14 at 17:50
  • @Calpratt this can be helpful if class composition hierarchy is fixed in compile time. I think grouping is unavailable in this situation. – k06a Nov 05 '14 at 18:32
  • @Calpratt this concrete example is better: http://stackoverflow.com/a/26718782/440168 – k06a Nov 05 '14 at 18:36