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

C++数据类型封装实现过滤视图复用的设计模式及编译问题咨询

问题2 编译错误原因

你遇到的编译错误是两个代码疏漏共同导致的:

  • 方法名不匹配:wrapper_interface 的data()方法中调用的是derived()->data_(),但你在wrapper、filtered_wrapper中实现的对外方法名是data(),缺少末尾的下划线,导致名称查找失败,连锁引发do_stuff的参数类型推导异常,最终抛出匹配失败错误。
  • CRTP模板参数填写错误:filtered_wrapper 继承wrapper_interface时,第一个模板参数(CRTP要求的派生类自身类型)错误填成了wrapper,而非filtered_wrapper。当你继承filtered_wrapper生成special_filtered_wrapper时,CRTP的静态向下转型会错误转为wrapper*类型,进一步加剧了类型匹配问题。
问题1 替代实现方案

如果你想继续沿用现有CRTP方案,可以先给wrapper_interface加完美转发构造函数,解决多层继承下的非默认构造问题:

template < class Derived, class Base, class DataType >
class wrapper_interface : Base {
public:
    // 新增完美转发构造函数,将参数转发给Base类构造
    template<typename... Args>
    wrapper_interface(Args&&... args) : Base(std::forward<Args>(args)...) {}

    virtual ~wrapper_interface() = default;
    // 其余原有逻辑不变
};

修改后你用第二种CRTP继承方案定义special_filtered_wrapper时,就可以在自身构造函数中传参给filtered_wrapper的构造函数,完成filtered_data_type的初始化。

如果不想用CRTP,提供两个完全不需要暴露模板给用户、也不用重写10个公共方法的方案:

方案1:非虚接口(NVI) + 类型擦除

把所有公共方法放到非模板的公共基类wrapper_base中,基类声明纯虚的内部数据获取接口,各个子类实现该接口返回自身持有的数据实例。公共方法内部调用该虚接口拿到数据后,在实现侧完成类型转换和do_stuff调用。头文件中只暴露基类的公共方法声明,所有实现逻辑都可以放到cpp文件中,完全不会暴露内部的data_type和模板逻辑。

方案2:宏复用代码

把10个公共方法的实现封装为一个宏定义,在wrapper、filtered_wrapper等各个类的定义内部展开宏即可,不需要写重复代码,也不会引入任何模板。对于只有10个固定方法的场景,这个方案最轻便,维护成本极低,用户侧完全看不到内部实现细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 17:36:05