为何依赖运行时输入实例化模板却未报错且输出符合预期?
问题:模板明明是编译期展开,为何这段代码能根据运行时输入选择实例化类型?
我知道模板是在编译期展开的,但下面的示例里,我根据运行时的用户输入决定模板实例化的类型,却仍能得到预期输出,请问这段代码为何能正常运行?
#include <iostream> using namespace std; template<typename T> class Demo { T Value = 20.67; public: void print(T val) { std::cout << "value :" << val << std::endl; } T getValue() { return Value; } }; int main() { int a; std::cout << "Enter value for a :"; std::cin >> a; if(a == 10) { Demo<int> demoObj1; demoObj1.print(demoObj1.getValue()); } else { Demo<float> demoObj2; demoObj2.print(demoObj2.getValue()); } }
输出示例:
- 输入a为10时:
Enter value for a :10 value :20 - 输入a为7时:
Enter value for a :7 value :20.67
代码正常运行的原因
核心逻辑是:编译器在编译阶段已经生成了所有可能的模板实例,运行时只是选择执行哪一段预编译好的分支代码。
- 编译期完成所有模板实例化
编译器处理代码时,会扫描到Demo<int>和Demo<float>这两个明确的模板实例化请求——不管运行时用户输入是什么,编译器都会在编译阶段把这两个类的代码分别展开、编译成独立的二进制代码:
Demo<int>中,Value会被隐式转换为int类型的20,getValue()返回int,print()接收int参数;Demo<float>中,Value保留浮点值20.67,getValue()返回float,print()接收float参数。
- 运行时仅做分支执行选择
程序运行时,用户输入的a只是决定执行if还是else分支:
- 输入10时,执行
Demo<int>对象的创建与调用逻辑; - 输入其他值时,执行
Demo<float>对象的创建与调用逻辑。
这本质是运行时选择执行哪一段已经编译好的代码,而非在运行时才实例化模板,完全符合模板“编译期展开”的特性。
内容的提问来源于stack exchange,提问作者Mangy
相关产品推荐
相关产品推荐

