CRTP to avoid virtual member function overhead

本小妞迷上赌 提交于 2019-12-03 21:11:08

The whole point of this pattern is, as far as I understand, that you can pass arguments simply as template <typename T> base<T> & and your interface is defined by (non-virtual) functions in base<T>. If you don't have an interface that you want to define (as you are suggesting in the second part of your question), then there's no need for any of this in the first place.

Note that you are not "imposing" an interface like with pure virtual functions, but rather you are providing an interface. Since everything is resolved at compile time, "imposing" isn't such a strong requirement.

In your replacement code you can't "polymorphically" call foo on a base<T>.

However it seems that the derived class does not require a definition to compile as it inherits one (the code compiles fine without defining a my_type::foo).

C++ is lazy : it will not try to make base<my_type>::foo() if you do not actually use it. But if you try to use it, then it will be created and if that fails, compilation errors will flow. But in your case, base<my_type>::foo() can be instanciated just fine :

template <class Derived>
struct base {
  void foo() {
    static_cast<Derived *>(this)->foo();
  };
};

struct my_type : base<my_type> {};

void func() {
    my_type m;
    static_cast<base<my_type>& >(m).foo();
}

will compile just fine. When the compiler is presented with static_cast(this)->foo(), it will try to find a foo() that is accessible in my_type. And there is one: it's called base<my_type>::foo(), which is public from a publicly inherited class. so base<my_type>::foo() calls base<my_type>::foo(), and you get an infinite recursion.

No, imagine the following situation:

template <typename T>
void bar(base<T> obj) {
   obj.foo();
}

base<my_type> my_obj;
bar(my_obj);

Base's foo will be called instead of my_type's...

Do this, and you will get your erro message:

template <class Derived>
struct base {
  void foo() {
    sizeof(Derived::foo);
    static_cast<Derived *>(this)->foo();
  };
};

But I must confess I am not sure how this will work in compilers other than GCC, tested only with GCC.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!