文章

CRTP:使用笔记

1. 动态继承运行时时间损耗

  • 每个 virtual 方法,都需要通过指针查找到虚函数入口(间接寻址),且可能引起I-Cache cache miss
  • virtual 方法,不能被优化为inline,针对一些短小的函数,时间损耗较大;

2. CRTP 使用举例:子类也是 template 模板类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename DerivedT>
class HoleDetectorBase {
 public:
  using underlying_type = HoleDetectorBase<DerivedT>;
  //...
};

template <typename condPairFuncT, typename condGHIPairFuncT>
class HoleDetector2 : public HoleDetectorBase<HoleDetector2<condPairFuncT, condGHIPairFuncT>> {
 public:
  using base_t = HoleDetectorBase<HoleDetector2<condPairFuncT, condGHIPairFuncT>>;
  using typename base_t::underlying_type;

  //...
};
  • 继承写法为:HoleDetector2<condPairFuncT, condGHIPairFuncT>,即带上template参数。

2.1 添加在基类中封装子类的函数

1
2
3
4
5
6
7
8
9
template <typename DerivedT>
class HoleDetectorBase {
//...

DerivedT& underlying() { return static_cast<DerivedT&>(*this); }
DerivedT const& underlying() const { return static_cast<DerivedT const&>(*this); }

//...
};
  • Note:基类中不能引用子类中的子类型,因为对父类而言,子类是incomplete type

3. 子类中使用 CRTP 父类的成员方法

子类中使用父类的成员函数,需要加上base_t::前缀,或者this指针。

1
auto groups = base_t::group_holes(valid_holes);

4. 参考资料

本文由作者按照 CC BY 4.0 进行授权