C++如何在模板函数中生成同模板类不同参数的新实例?
实现方案
你原来的代码存在两个核心问题:
- 类内定义的
using MY_NAME = Foo是注入类名,指代当前实例化的具体类型Foo<COUNT>,并非类模板,无法再接参数实例化 in是对象实例,不能直接用::访问类型成员,访问依赖类型的嵌套模板时还需要加template关键字消除语法歧义
以下是两种可行的实现方案:
方案1:侵入式实现(修改原有模板类)
适合你可以控制原有类定义的场景,仅需要调整类内别名声明即可:
#include <iostream> using uint = unsigned int; template <uint COUNT> class Foo { public: // 声明模板别名,用于重绑定模板参数 template<uint N> using Rebind = Foo<N>; void print() { std::cout << "Foo<" << COUNT << ">::print called\n"; } private: int data[COUNT]; }; template <class T> void my_function(T in) { // 依赖类型的嵌套模板需要加template关键字消除歧义 using Foo1Type = typename T::template Rebind<1>; Foo1Type x{}; x.print(); } int main() { my_function(Foo<5>{}); // 输出 Foo<1>::print called return 0; }
方案2:非侵入式实现(无需修改原有类)
如果不能修改原有模板类,可以通过模板特化做类型萃取,自动提取输入类型对应的类模板再替换参数,通用性更强:
#include <iostream> using uint = unsigned int; // 原有Foo类无需做任何修改 template <uint COUNT> class Foo { public: void print() { std::cout << "Foo<" << COUNT << ">::print called\n"; } private: int data[COUNT]; }; // 通用萃取模板 template<typename T> struct rebind_to_1; // 特化匹配所有接收单个uint非类型参数的模板类 template<template<uint> class TemplateCls, uint OldParam> struct rebind_to_1<TemplateCls<OldParam>> { using type = TemplateCls<1>; }; // 便捷调用别名 template<typename T> using rebind_to_1_t = typename rebind_to_1<T>::type; template <class T> void my_function(T in) { rebind_to_1_t<T> x{}; x.print(); } int main() { my_function(Foo<5>{}); // 输出 Foo<1>::print called return 0; }
如果需要支持多参数、不同类型的模板类,仅需要调整萃取模板的特化匹配规则即可。
注意事项
- 所有操作都在编译期完成,不会产生额外运行时开销
- 如果要适配类型参数、模板模板参数等不同形式的模板,扩展对应特化规则即可
内容的提问来源于stack exchange,提问作者Eyal
相关产品推荐
相关产品推荐

