C++的CRTP所带来的静态多态功能具体有什么用?

一个常见的例子是 template<typename Derived> class Animal { public: void eat() { sta…
关注者
133
被浏览
54,819

14 个回答

模板给C++带来了类似duck type的用法,直接写func(AnimalT&) 当然是可以的,但是这样只是ducktype。当你想要迭代vector<Animal*>的时候,由于Lion和Cat不是同一个类型,也没有派生同一基类,这种写法是构建不了vector<T>的。

CRTP的存在是为了消除vtable,避免动态查找vfunc的开销,用到多态的地方都可以用CRTP来改写。然而轮子哥评论里也有人问了,这里Lion*和Cat*因为模板参数不同,还是不同的类型。为了解决这样的需求,需要让Aminal<T>继承一个公共的非模板基类比如Animal_Base,当然虚函数该加还得加。

CRTP另外的用处就是定义抽象方法,以及用来实现表达式计算等。因为基类是模板类,所以在编译时可以随意调用T.fun()而不需要声明,子类只需要给出fun()的实现即可实现功能。比如对于数值计算中常用的矢量Vec,算法和其长度往往是无关的,故Vec2,Vec3,Vec4这种子类都应该继承Vec_Base<T>这一基类,然后如果基类中定义了一个这样的一个公共函数 alg(),里面调用了子类的函数fun1()和fun2(),并进行了进一步的计算。这时,对不同的子类,只需要给出不同的函数实现即可获得各自的alg(),避免了重复定义相同的操作。即将公共的方法的实现抽出来,调用子类各自的实现。

template<class T>                        
class Vec_Base{                          
public:                                  
    T& get(){                            
        return static_cast<T&>(*this);