C++模板:CRTP

295 阅读1分钟

CRTP,Curiously Recurring Template Pattern(奇特的递归模板模式)代表了类实现技术中一种通用的模式,即派生类将本身作为模板参数传递给基类。它的实现形式有:

  1. 最简单的情形。CRTP有一个非依赖型基类Curious不是模板,因此免于与依赖型基类CuriousBase的名字可见性等问题纠缠
template <typename Derived>
class CuriousBase {
    ......
};
class Curious : public CuriousBase<Curious> {
    ......
};

2.非依赖型基类是模板

template <typename Derived>
class CuriousBase {
    ......
};
template <typename T>
class CuriousTemplate : public CuriousBase<CuriousTemplate<T> > {
    ......
};
  1. 模板的模板参数
template <template<typename> class Derived>
class MoreCuriousBase {
    ......
};
template <typename T>
class MoreCurious : public MoreCuriousBase<MoreCurious>{ 
    ......
};

实际应用

  1. 记录某个类的对象构造的总个数。完整实现和测试代码
template <typename CountedType>
class ObjectCount {
public:
    uint64_t live() { return count; }
protected:
    ObjectCount() { ++count; }
    virtual ~ObjectCount() {--count; }
    ObjectCount(const ObjectCount& obj) { ++count; }
    ObjectCount operator = (const ObjectCount& obj) {
        ObjectCount res;
        ++count;
        return res;
    }
private:
    static uint64_t     count;
};
template <typename CountedType>
uint64_t ObjectCount<CountedType>::count = 0;

template<typename T>
class MyCRTP : public ObjectCount<MyCRTP<T> > { };

  1. 用于实现“编译时多态性(compile-time polymorphism)”,基类公开接口,而派生类实现该接口。完整实现和测试代码
template<typename Derived>
class Base {
public:
    void name() {
        (static_cast<Derived*>(this))->impl();
    }
};

class Derived1 : public Base<Derived1>{
public:
    void impl() {
        std::cout << "Derived1::impl" << std::endl;
    }
};