开发者

This is CRTP usage for static polymorphism but without implementation of a derived function. Compiles both in gcc and visual studio. Why?

#include <iostream>

template <class Derived>
class Base
{
public:
  void method1()
  {
    static_cast<Derived*>(this)->method1(开发者_开发问答);
  }

  void method2()
  {
    static_cast<Derived*>(this)->method2();
  }
};

class Derived1: public Base<Derived1>
{
public:
  void method1()
  {
    std::cout << "Method 1 of Derived1 executed.\n";
  }
};

int main(int argc, char *argv[])
{
  Derived1 d1;
  d1.method1();
  d1.method2();
  return 0;
}

Follow up question: How to I make this type safe? That is, If someone forgets to implement method2, I would like the compiler to catch it. I don't want this to blow up at runtime.


I think the reason that this is valid is that if you instantiate this code:

void method2()
{
  static_cast<Derived*>(this)->method2();
}

where Derived does not have an implementation of method2() will essentially be a glorified self-recursive call. The reason here is that in Derived1, there is indeed a member function called method2, namely the one inherited from the base class.

I tried running this code, and sure enough the call to method2 caused a stack overflow from self-recursion.

Normally, the CRTP avoids this by not having the base class function call a derived class function of the same name. That way, if the derived class is missing a particular function, the call triggers a compiler error. In your case, this doesn't happen because the function itself could be referenced indirectly from the base class.


  Derived1 d1;
  d1.method2();

Even though Derived1 doesn't define method2(), it gets it by inheriting Base anyway. That is why it compiles and runs. d1.method2() actually calls Base::method2(), which again calls itself. It's a recursive call.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜