在现代 C++(尤其是 C++17/20)中,模板元编程已成为实现高度可组合、零运行时开销代码的强大工具。本文将演示如何使用模板元编程在编译时构建一个类型安全、可扩展的工厂函数,既不需要运行时反射,也不需要手动维护映射表。
1. 需求分析
假设我们有一组类:Button, Label, Textbox 等,它们都继承自同一基类 Widget。我们想实现一个统一的 createWidget 接口,接受字符串标识(如 "button")并返回对应类型的 `std::unique_ptr
`,同时确保:
– **类型安全**:编译期就能验证标识与类的对应关系。
– **可扩展**:新增类时只需在一个地方声明,而不必手动修改映射。
– **无运行时成本**:所有映射表和判断均在编译期完成。
#### 2. 基础设施:类型列表
C++17 引入了折叠表达式和 `if constexpr`,它们与 `std::tuple` 能很好地配合,实现编译时遍历。
“`cpp
#include
#include
#include
#include
#include
// 基类
struct Widget { virtual ~Widget() = default; };
// 示例派生类
struct Button : Widget { Button() { /*…*/ } };
struct Label : Widget { Label() { /*…*/ } };
struct Textbox: Widget { Textbox(){ /*…*/ } };
// 通过 std::tuple 保存所有可创建的类型
using WidgetList = std::tuple