C++03环境下用模板元编程替代预处理器指令的方案咨询
嵌入式C++03多设备适配的模板设计问题
背景
我维护一个嵌入式C++03代码库,需要支持不同厂商的设备,但每个项目仅会使用其中一种。大部分函数在各设备间通用,但存在少数专属函数,这些专属函数带来了维护上的麻烦。目前已有5种设备类型,预计还会新增至少2种,原有的预处理器实现已逐渐变得杂乱,急需重构优化。
预处理器实现(可行但繁琐)
最初采用预处理器条件编译实现,但随着类型增加,代码会越来越难以维护:
#define HW_TYPE1 0 #define HW_TYPE2 1 #define HW_TYPE HW_TYPE1 struct GadgetBase { void FncA(); // 大量通用方法 void FncZ(); }; #if HW_TYPE==HW_TYPE2 struct Gadget : public GadgetBase { bool Bar() {return(true);} }; #else struct Gadget : public GadgetBase { bool Foo() {return(false);} }; #endif Gadget A; #if HW_TYPE==HW_TYPE2 bool Test() {return(A.Bar());} #else bool Test() {return(A.Foo());} #endif
模板尝试的编译问题
我尝试用模板替代预处理器,但Test()的定义无法通过编译——根据全局Type的取值,Foo()或Bar()总有一个未定义:
enum TypeE { eType1, eType2 }; const TypeE Type= eType1; // 设置全局设备类型 // 所有设备通用的基类 struct GadgetBase { void FncA(); // 大量通用方法 void FncZ(); }; // 各设备专属的模板类 template<TypeE E= eType1> struct Gadget : public GadgetBase { bool Foo() {return(false);} }; template<> struct Gadget<eType2> : public GadgetBase { bool Bar() {return(true);} }; Gadget<Type> A; template<TypeE E= eType1> bool Test() {return(A.Foo());} template<> bool Test() {return(A.Bar());}
核心需求与疑问
- 希望通过模板实现,减少新增设备类型或专属函数时的代码改动量
- 设备相关代码仅占总代码库的一小部分,按设备拆分整个项目并不现实
- 每个项目仅使用一种设备类型,但未使用的类型仍需能正常编译
- 受限于C++03标准,无法使用constexpr、const if等特性
请问在C++03环境下,最佳的设计方案是什么?我的模板思路是否完全错误?我愿意进行彻底重构。
补充:LSP合规性担忧
在思考解决方案时,我担心设计违反里氏替换原则(LSP),尝试将Test()作为接口部分重构,有两种思路:
思路1:基于虚函数的接口
struct GadgetI { virtual bool Test()=0; }; template<TypeE E= eType1> struct Gadget : public GadgetBase, public GadgetI { bool Foo() {return(false);} bool Test() {return Foo();} }; template<> struct Gadget<eType2> : public GadgetBase, public GadgetI { bool Bar() {return(true);} bool Test() {return Bar();} }; template<> struct Gadget<eType3> : public GadgetBase, public GadgetI { bool Test() {} // 这是否违反LSP? };
思路2:模板特化的Test函数
template<typename T> bool Test(T& o) {} // 这是否违反LSP? template<> bool Test(Gadget<eType1> &o) {return(o.Foo());} template<> bool Test(Gadget<eType2> &o) {return(o.Bar());} Test(A);
我可能过度思考了,但不想因当前设计留下隐患。
内容的提问来源于stack exchange,提问作者willdo
相关产品推荐
相关产品推荐

