为什么我在运行时实例化模板参数,但我得到预期的输出,而不是错误ie.我们不能在运行时展开模板?



我知道模板在编译时扩展,但在下面的例子中我正在决定或做模板实例化在运行时取决于用户输入,但我仍然得到预期的输出。这是怎么运行的?谁能给我解释一下

#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


value: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,否则代替constexpr if

另一方面,如果您要使用constexpr if,那么Demo<int>Demo<float>中只有一个会被实例化。注意,在这个例子中,我们不能使用constexpr if,因为输入来自user.

相关内容

最新更新