MLIR CRTP 惯用法

1. 什么是 CRTP

Curiously Recurring Template Pattern。子类作为父类模板参数,父类用 static_cast<T*>(this) 调用子类方法,实现编译期多态。

2. 代码示例

#include <iostream>

// 父类:模板参数 T 必须是继承它的子类
template <typename T>
struct Base {
  // 通过 static_cast 将 this 转换为子类指针,再调用子类的 hello()
  void hello() {
    static_cast<T*>(this)->hello();
  }
};

// 子类:传入自己作为父类模板参数
struct Derived : Base<Derived> {
  void hello() {
    std::cout << "Hello from Derived\n";
  }
};

int main() {
  Derived d;
  Base<Derived>* ptr = &d;  // 父类指针指向子类对象
  ptr->hello();             // 实际调用到 Derived::hello()
}

3. 为什么 CRTP 无 vtable 开销

vtable 只在 ptr->virtual_fn() 通过父类指针调用虚函数时才会触发。CRTP 中调用 hello() 的是子类指针,不是父类。

4. MLIR 中的 CRTP

// mlir/IR/OpDefinition.h
template <typename ConcreteType, typename... Traits>
class Op : public Op<ConcreteType>::template Impl<Traits...> {
  Operation* getOperation() {
    // static_cast 实现静态多态,无虚表查找
    return static_cast<ConcreteType*>(this)->getOperation();
  }
};

TableGen 生成的 trait 接口代码大量使用此模式,所有 trait 方法在编译时绑定,实现零运行时开销的验证逻辑。

posted @ 2026-05-23 01:48  judesongd  阅读(6)  评论(0)    收藏  举报