C++如何遍历模板变量vec的全部实例化对象并统一执行公共逻辑
实现方案:利用模板静态变量自动注册追踪实例
核心原理是借助C++模板的特性:每个不同类型参数的模板实例只会初始化一次,通过静态变量的初始化钩子自动把每个模板变量实例注册到全局追踪容器中,不需要手动枚举实例化类型。
具体实现步骤
1. 定义全局追踪容器与注册逻辑
我们用全局列表存储所有模板实例对应的公共操作函数,利用模板类的静态成员在首次使用时自动初始化的特性完成注册:
#include <vector> #include <iostream> #include <functional> #include <list> #include <typeinfo> // 全局追踪列表,存储所有vec实例对应的公共操作 inline std::list<std::function<void()>> vec_operation_list; // 原模板变量定义 template<class T> std::vector<T> vec{}; // 自动注册器,每个T对应一个实例,首次使用时自动注册操作 template<class T> struct VecInstanceRegister { VecInstanceRegister() { // 这里可自定义所有实例支持的公共逻辑,用concept可提前校验接口合法性 vec_operation_list.emplace_back([]() { // 示例逻辑:打印当前类型vec的大小后清空 std::cout << typeid(T).name() << " 类型vec的元素数量:" << vec<T>.size() << std::endl; vec<T>.clear(); }); } // 静态占位成员,触发注册逻辑的入口 static inline VecInstanceRegister register_obj{}; }; // 封装vec的访问接口,确保每次访问vec<T>时先触发注册 #define GET_VEC(T) (VecInstanceRegister<T>::register_obj, vec<T>)
2. 业务使用示例
int main() { // 按正常逻辑使用vec,无需额外手动注册 GET_VEC(short).push_back(5); GET_VEC(int).push_back(10); GET_VEC(long int).push_back(15); // 遍历所有已实例化的vec,执行公共操作 for (auto& op : vec_operation_list) { op(); } return 0; }
扩展说明
- 如果需要操作实例本身而非预定义操作,可以把追踪列表的元素类型改为
std::any或者公共基类指针,遍历后按需转型使用,配合concept可以完全避免非法类型的转型问题。 - 所有注册逻辑都在编译期完成,没有运行期的额外开销,也不会遗漏任何被访问过的模板实例。
- 如果不需要宏封装,也可以写模板访问函数替代宏,效果完全一致。
内容的提问来源于stack exchange,提问作者selamba
相关产品推荐
相关产品推荐

