模板;constexpr;编译时

6

I have several questions

1)

#include <iostream>
template<typename T>
void func(T t){}


int main()
{
 int i;
 double d;
 std::cin>>i;

if(i==1)
 func(i);
else
 func(d);
}

什么时候(运行时/编译时)需要生成所需的函数?实例化后有多少个版本的函数?

2) 以下两种方式之间有什么区别:

template<typename T> auto func(T t){return 0;}

并且

template<typename T> constexpr auto func(T t){return 0;}

据我理解,template在编译时起作用,constexpr也是如此。为什么(以及何时)需要在模板中使用constexpr


"在(运行时/编译时),何时生成所需的函数?" 当然是在编译时。 "实例化后有多少个函数版本?" 取决于需要实例化的上下文中使用的数量。 - Igor Tandetnik
1
(2)第二个版本可用于需要编译时常量的情况,例如:int arr[func(42) + 1];。大致上,对于函数而言,constexpr 的意思是“这个函数足够简单和自包含,以至于编译器可以在编译时执行它;如果参数在编译时已知,则结果也可以在编译时得出”。这与 template 无关 - 您可以轻松地拥有一个非模板的 constexpr 函数或一个 constexpr 函数模板。 - Igor Tandetnik
1个回答

8

答案(1): 有两个版本。

答案(2): 函数实例化和执行是两个不同的概念。模板函数在编译时被实例化,但并不意味着它会在编译时执行。constexpr 在这种情况下是不同的,因为它可以根据调用它的上下文和参数,在编译时生成和执行。想象一个声明为这样的函数:

constexpr double myfunc(int x)

现在如果您这样调用它
constexpr double d1 = myfunc(1);
double d2 = myfunc(1);

您将在编译时计算d1的值,而d2将在运行时计算。 constexpr与模板无关,但您可以将它们混合在一起使用。例如,在这里,myfunc可以成为模板化函数。执行时间是编译时还是运行时,取决于因素(如上所述)。

使用对象时,constexpr会确保它们在编译时初始化(因此默认为const)。这就是为什么在上面的情况中,“context”对于d1强制执行myfunc在编译时执行的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接