正如我所知,模板是在编译时扩展的,但在下面的例子中,我决定或做模板示例化在运行时取决于用户输入,但我仍然得到预期output.how这运行?有人能解释我吗
#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
2条答案
按热度按时间u0njafvf1#
在编译时,两个模板都被创建。在编译的程序中存在两个分支的代码。在运行时,您只需选择要执行的分支。
编译器会看到代码的两个分支,但意识到它无法在编译时确定执行哪个分支,因此它会为两个分支都生成代码。如果编译器在编译时确定某个分支不可能被执行,编译器可能会将其优化掉。下面是一个简单的情况:
在这种情况下,编译器可以看到第二个分支永远不会被执行。编译器最初会编译两个分支,但随后可能会从最终的可执行文件中丢弃第二个分支。编译器是否这样做取决于编译器的实现和编译标志。
可以使用
if constexpr
强制编译器拒绝未使用的分支。所做的更改只是此示例使用
if constexpr
。在此示例中,第二个分支将不会完全编译(仍会检查语法是否正确,但不会生成程序集)。第二个分支的代码将不存在于可执行文件中。vmdwslir2#
Demo<int>
和Demo<float>
都将在编译时示例化,因为您使用的是普通的(非常量表达式)if,else而不是constexpr if
。另一方面,如果你使用
constexpr if
,那么只有Demo<int>
或Demo<float>
中的一个会被示例化。注意,在这个例子中我们不能使用constexpr if
,因为输入来自用户。