在C ++中,是否可能使用带有或不带有编译时间常数的相同代码?

use*_*078 4 c++

说你有一个像这样的功能:

double do_it(int m)
{
   double result = 0;

   for(int i = 0; i < m; i++)
      result += i;

   return result;
}
Run Code Online (Sandbox Code Playgroud)

如果您在编译时知道m,则可以执行以下操作:

template<size_t t_m>
double do_it()
{
   double result = 0;

   for(int i = 0; i < t_m; i++)
      result += i;

   return result;   
}
Run Code Online (Sandbox Code Playgroud)

在优化时,这为诸如循环展开之类的事情提供了可能性。但是,有时您可能在编译时知道一些情况,而在运行时知道一些情况。或者,也许您有可以由用户更改的默认值...但是优化默认情况会很好。

我想知道是否有任何方法可以提供两个版本而基本上不复制代码或使用宏?

注意,以上是说明这一点的玩具示例。

Nic*_*las 5

就语言规范而言,没有通用的方法可以使功能按您期望的方式工作。但这并不意味着编译器无法为您完成此任务。

在优化时,这为诸如循环展开之类的事情提供了可能性。

您这样说,好像编译器无法展开循环。

编译器可以展开模板循环的原因是由于以下方面的融合:

  1. 编译器具有函数的定义。在这种情况下,函数定义设置(这是一个模板函数,所以它的定义须提供)。

  2. 编译器具有循环计数器的编译时值。在这种情况下,通过template参数。

但是这些因素都没有明确要求模板。如果编译器具有函数的定义,并且可以确定循环计数器的编译时值,则它具有展开该循环所需的信息的100%。

它如何获取此信息无关紧要。它可以是一个inline函数(必须提供定义),在给定编译时常量作为参数的情况下可以调用该函数。它可能是一个constexpr函数(同样,您必须提供定义),在给定编译时常量作为参数的情况下调用它。

这是实施质量的问题,而不是语言的问题。如果将编译时参数当作一件事情,那将是支持您否则无法做的事情,不支持优化(或者至少不支持编译器优化)。例如,您不能有一个函数返回std::array的长度由常规函数参数而不是模板参数指定。