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

如何实现仅允许派生类传入自身作为参数的CRTP模板基类

解决方案

你遇到的是奇异递归模板模式(CRTP)场景下的典型校验时机问题:模板参数列表中的std::is_base_of校验触发时,基类Self和派生类T都处于不完整状态,类型特性无法正常计算结果。

最简洁且兼容性最优的实现方案是利用友元权限限制实现约束,仅允许模板参数对应的类继承当前基类实例:

#include <type_traits>

template <class T>
class Self {
protected:
    typedef T self;
    // 可选:增加类型校验,确保T是类类型
    static_assert(std::is_class<T>::value, "Template parameter T must be a class type");
private:
    // 构造函数私有,仅友元可访问
    Self() = default;
    // 仅模板参数T有权限访问基类的私有构造函数
    friend T;
};

// 编译正常:ValidDerived是基类的友元,可以调用基类构造函数
class ValidDerived : public Self<ValidDerived> { };

// 编译报错:InvalidDerived不是Self<ValidDerived>的友元,无法调用基类私有构造函数
class InvalidDerived : public Self<ValidDerived> { };

该方案完全匹配你的需求:

  • 只有派生类传入自身作为模板参数时才能正常编译
  • 可以直接通过self别名获取派生类类型,直接调用typeid(self).name()即可拿到最派生类的类型名称,满足反射场景的需求。

如果需要更明确的错误提示,可以在C20及以上版本结合concept做进一步约束,上述友元方案兼容C11及所有后续标准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:39:05