You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确继承Halide::Generator派生类,避免抽象基类实例化及参数缺失问题

问题原因分析

第一个编译错误的根源

你定义的Base类直接继承了Halide::Generator<Base>,Halide的Generator模板机制会对所有继承了Halide::Generator<T>的类自动实例化内部的create()方法,该方法会尝试new一个T类型的实例,哪怕你没有注册Base类,这个模板实例化逻辑也会执行。而Base是包含纯虚函数的抽象类,无法被实例化,因此触发编译错误。

第二个参数缺失问题的根源

当你把Base改成非抽象类后,Halide的Generator参数是在模板实例化阶段静态收集的,你的派生类没有单独继承Halide::Generator<派生类类型>,因此派生类中定义的gain/offset参数不会被Halide的参数收集逻辑识别,最终生成的函数签名自然不会包含这些参数。


解决方案

采用模板化的基类+CRTP模式实现继承,避免基类被Halide的Generator机制实例化,同时保证派生类的参数能被正确收集。

修改后的my_generators.cpp代码

#include "Halide.h"
#include <stdio.h>

using namespace Halide;

// 模板化的抽象基类,不继承Halide::Generator,不会被实例化
template<typename Derived>
class Base {
public:
    Input<Buffer<float>> input{"input", 2};
    Output<Buffer<float>> output{"brighter", 2};
    Var x, y;

    virtual Func process(Func input) = 0;

    void generate() {
        output = process(input);
        output.vectorize(x, 16).parallel(y);
    }
};

class DerivedGain : public Halide::Generator<DerivedGain>, public Base<DerivedGain> {
public:
    // 导入基类成员到当前作用域,避免名字查找失败
    using Base<DerivedGain>::input;
    using Base<DerivedGain>::output;
    using Base<DerivedGain>::x;
    using Base<DerivedGain>::y;

    Input<float> gain{"gain"};

    Func process(Func input) override {
        Func result("result");
        result(x,y) = input(x,y) * gain;
        return result;
    }
};

class DerivedOffset : public Halide::Generator<DerivedOffset>, public Base<DerivedOffset> {
public:
    using Base<DerivedOffset>::input;
    using Base<DerivedOffset>::output;
    using Base<DerivedOffset>::x;
    using Base<DerivedOffset>::y;

    Input<float> offset{"offset"};

    Func process(Func input) override {
        Func result("result");
        result(x,y) = input(x,y) + offset;
        return result;
    }
};

HALIDE_REGISTER_GENERATOR(DerivedGain, derived_gain)
HALIDE_REGISTER_GENERATOR(DerivedOffset, derived_offset)

逻辑说明

  1. 基类修改为模板类,不再继承Halide::Generator,不会触发Halide的实例化逻辑,纯虚函数的存在也不会导致编译错误。
  2. 每个派生类分别继承Halide::Generator<自身类型>,完全符合Halide Generator的定义要求,派生类中定义的专属参数会被Halide的静态参数收集机制正确识别。
  3. 通过using声明将基类成员导入派生类作用域,避免编译时名字查找失败。

修改后重新编译,生成的头文件会自动包含gain/offset参数,符合预期。


内容的提问来源于stack exchange,提问作者tuscasp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:45:11