繁体   English   中英

为什么即使我在运行时实例化模板参数,但我得到预期的 output 而不是错误,即。 我们不能在运行时扩展模板?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM