如何声明类型容器?模板实例化类型存储方案问询
问题原因
你写的代码编译失败的核心问题是:模板参数必须是编译期常量,但std::vector<std::type_info>是运行时容器,myTypes[0]是只有运行时才能确定的值,完全没法作为模板实参传给myFunc。
下面给你几种可行的实现方式:
方案1:编译期类型列表(最贴合模板特性)
如果你的目标类型列表是固定的(编译期就能确定),别用vector,改用编译期的类型集合(比如std::tuple或自定义类型列表),再通过编译期遍历的方式实例化模板。
示例代码:
#include <tuple> #include <iostream> // 假设你的模板函数实现如下 template<typename T> void myFunc() { std::cout << "实例化myFunc<" << typeid(T).name() << ">" << std::endl; } // 辅助模板:展开tuple的所有类型并实例化 template<typename... Ts> struct TupleInstantiator { static void run() { // C++17折叠表达式,逐个触发模板实例化 (myFunc<Ts>(), ...); } }; template<typename Tuple> struct InstantiateFromTuple; template<typename... Ts> struct InstantiateFromTuple<std::tuple<Ts...>> : TupleInstantiator<Ts...> {}; int main() { // 用tuple存储允许的编译期类型列表 using AllowedTypes = std::tuple<int, float, std::string>; // 一次性实例化所有类型对应的myFunc InstantiateFromTuple<AllowedTypes>::run(); return 0; }
方案2:运行时函数表(支持动态关联)
如果必须在运行时根据类型信息触发模板实例化,可以提前把所有允许的类型对应的模板实例化函数指针存入哈希表,通过std::type_index作为键来查找调用。
示例代码:
#include <unordered_map> #include <typeindex> #include <iostream> #include <string> template<typename T> void myFunc() { std::cout << "调用myFunc<" << typeid(T).name() << ">" << std::endl; } // 提前初始化函数表,存入所有允许的类型对应的函数指针 std::unordered_map<std::type_index, void(*)()> typeFuncMap = { {typeid(int), &myFunc<int>}, {typeid(float), &myFunc<float>}, {typeid(std::string), &myFunc<std::string>} }; int main() { // 运行时根据类型信息查找并调用 auto iter = typeFuncMap.find(typeid(int)); if (iter != typeFuncMap.end()) { iter->second(); // 执行myFunc<int>() } return 0; }
方案3:自定义编译期类型列表(更灵活的元编程)
如果需要对类型列表做更复杂的编译期操作,可以自己实现一个类型列表模板:
#include <iostream> #include <string> // 自定义类型列表模板 template<typename... Ts> struct TypeList {}; // 递归遍历类型列表的辅助模板 template<typename List> struct TypeListInstantiator; // 递归终止条件:空类型列表 template<> struct TypeListInstantiator<TypeList<>> { static void run() {} }; // 递归展开:处理第一个类型,再递归处理剩余类型 template<typename T, typename... Ts> struct TypeListInstantiator<TypeList<T, Ts...>> { static void run() { myFunc<T>(); TypeListInstantiator<TypeList<Ts...>>::run(); } }; template<typename T> void myFunc() { std::cout << "实例化myFunc<" << typeid(T).name() << ">" << std::endl; } int main() { using AllowedTypes = TypeList<int, float, std::string>; TypeListInstantiator<AllowedTypes>::run(); return 0; }
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

