[英]Why even i am instantiating template parameter at runtime but i am getting expected output instead of error ie. we cannot expand template at runtime?
据我所知,模板在编译时会扩展,但在下面的示例中,我决定或在运行时根据用户输入进行模板实例化,但我仍然得到预期的 output。这是如何运行的? 谁能给我解释一下
#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 的值
价值:20并输入 a:7 的值
价值:20.67
在编译时,将创建两个模板。 两个分支的编译程序中都存在代码。 在运行时,您只需选择要执行的分支。
编译器看到代码的两个分支,并意识到它无法在编译时确定将采取哪个分支,因此它会为两个分支生成代码。 如果编译器可以在编译时确定一个分支不可能被采用,编译器可能会优化它。 一个简单的情况是:
if (4 < 5) {
Demo<int> demoObj1;
demoObj1.print(demoObj1.getValue());
} else {
Demo<float> demoObj2;
demoObj2.print(demoObj2.getValue());
}
在这种情况下,编译器可以看到第二个分支永远不会被执行。 编译器最初会编译这两个分支,但随后它可能会从最终可执行文件中丢弃第二个分支。 编译器是否这样做取决于编译器实现和编译标志。
您可以使用if constexpr
强制编译器拒绝未使用的分支。 考虑以下示例:
if constexpr (4 < 5) {
Demo<int> demoObj1;
demoObj1.print(demoObj1.getValue());
} else {
Demo<float> demoObj2;
demoObj2.print(demoObj2.getValue());
}
所有改变的是这个例子使用if constexpr
。 在这个例子中,第二个分支不会被完全编译(它仍然检查语法是否正确,但汇编生成没有完成)。 第二个分支的代码将不存在于可执行文件中。
Demo<int>
和Demo<float>
都将在编译时实例化,因为您使用的是普通(非 constexpr) if, else 而不是constexpr if
。
另一方面,如果您要使用constexpr if
那么只会实例化Demo<int>
或Demo<float>
中的一个。 请注意,在此示例中,我们不能使用constexpr if
因为输入是从用户那里获取的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.