一篇文章吃透C++的CRTP(奇异递归模板)模式
CRTP(奇异递归模板)模式通过静态多态实现编译期多态,具有性能优势(无虚函数开销、支持内联优化)和编译时类型检查的优点,但会导致代码膨胀、增加编译复杂度且不支持动态加载。适用于高性能计算和嵌入式系统等场景。文中给出了CRTP的基本实现示例,并提供了四种扩展解决方案:1)非模板公共基类;2)类型擦拭技术;3)std::any/variant;4)命令包装器模式。其中方案1和方案4(基于多态和类型擦
·
CRTP(奇异递归模板)模式
机制:
静态多态(编译期确定)
优势:
性能优势: 1. 无虚函数调用开销 2. 支持内联,允许更多编译器优化 3. 零运行时开销的抽
象
编译时检查: 1. 类型安全, 编译器捕获错误 2. 方法不存在时会产生编译错误
劣势:
代码膨胀: 每个派生类都会实例化一套基类模板代码
编译时间: 增加编译时间和编译复杂度
接口不明确: 缺少明确的接口约束机制
不支持动态加载: 无法支持运行时动态库加载等场景
使用场景:
高性能计算 模板库设计 嵌入式系统等资源受限等环境
示例:
template <typename Derived>
class Command{
public:
void execute(const std::string& args){
static_cast<Derived*>(this)->executeImpl(args);
}
};
class AddCommand:public Command<AddCommand>{
public:
void executeImpl(std::string& args){
/* dosomething */
}
};
在CRTP模式实现多态的解决方法
1. 使用非模板公共基类:
class CommmandBase{
public:
virtual void execute(const std::string& args) = 0;
virtual ~CommmandBase() = default;
};
template <typename Derived>
class Command:public CommmandBase{
public:
void execute(const std::string& args){
static_cast<Derived*>(this)->executeImpl(args);
}
};
class DeleteCommand:public Command<DeleteCommand>{
public:
void executeImpl(std::string& args){
/* dosomething */
}
};
2. 使用类型擦拭技术
// 在映射表里存储std::function对象(调用类成员函数)
3. 使用std::any或者std::variant
std::unordered_map<std::string, std::any> commands;
commands["add"] = AddCommand();
std::any_cast<AddCommand&>(commands["add"]).executeImpl(args);
using CommandVariant = std::variant<AddCommand, DeleteCommand>;
std::unordered_map<std::string, CommandVariant> commands;
commands["delete"] = DeleteCommand();
std::visit([&args](auto&& cmd){cmd.executeImpl(args);}, commands["delete"]);
4. 创建命令包装器
class CommandWrapper{
struct Concept{
virtual void execute(const std::string& args) = 0;
virtual ~Concept() = default;
};
template <typename T>
struct Model : Concept {
T command;
Model(T command): command(std::move(command)){}
void execute(const std::string& args){
command.execute(args);
}
};
std::unique_ptr<Concept> impl ;
public:
template <typename T>
CommandWrapper(T cmd):impl(std::make_unique<Model<T>>(std::move(cmd))){}
void execute(const std::string& args){
impl->execute(args);
}
};
注释: 推荐使用方案1和方案4
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)