如何理解constexpr函数有“它需要的一切”来在编译时计算它的结果?

时间:2018-06-18 03:32:16

标签: c++ constexpr

我遇到了Demystifying constexpr,对这篇文章中的例子感到有点困惑。

根据帖子,constexpr function定义是这样的:

  

constexpr函数能够在编译时计算其结果   时间,如果在编译时知道其输入。

     

换句话说,任何具有“它需要的一切”来计算的函数   它在编译时的结果可以是一个常量表达式。

对于add函数:

int add(int a, int b)  
{
    return a + b;
}
  

虽然函数是constexpr,但您可以将其与运行时值一起使用   同样的:

int main(int argc, char argv)  
{
    return add(argc, argc);
}

但是对于另一个功能:

int add_vectors_size(const std::vector<int> & a, const std::vector<int> & b)  
{
  return a.size() + b.size()
}

对它的解释不能用作“constexpr”:

  

编译时输入是两个向量。我们可以在编译时知道吗   矢量的大小?答案是不。因此,add_vectors_size不能   是一个不变的表达。我们没有“我们需要的一切”。

但根据我的理解,对于第一种情况,argc值在编译时也无法知道,其值应该在运行时获得,对吗?因此,如何理解constexpr函数具有“它需要的一切”来计算 它在编译时的结果?

3 个答案:

答案 0 :(得分:3)

  

但根据我的理解,对于第一种情况,在编译时也无法知道argc值

您将“参数”与“参数”混淆。

参数是函数声明中表示用户传入的东西的东西。参数是用户在特定函数调用的站点传递的实际内容。

argc是一个论点。这个值可能是也可能不是常量表达式,如果不是,constexpr函数就可以了。

int用作add参数的类型。 int是一种可以是常量表达式的类型。现在,并非每个int值都是常量表达式,但它理论上可以是一个类型。

因此,add可以是constexpr函数,因为它的参数列表使用可以是常量表达式的类型。这与函数本身的性质有关。

类型vector<T> 永远不会是一个常量表达式(在C ++ 17中,无论如何)。因此,没有constexpr函数可以将一个作为参数。也不能在内部使用它。

答案 1 :(得分:2)

函数成为constexpr函数的关键要求:

  

如果在编译时知道其输入,则可以在编译时计算其结果。

但是,constexpr也是常规功能。如果仅在运行时知道其输入,则其结果将在运行时计算。

根据您的示例,如果您使用:

 constexpr int a = add(5, 10);

函数调用的结果可以在编译时计算,因为它的输入在编译时是已知的。

使用

return add(argc, argc);

也是该功能的有效使用。此调用中函数的输入仅在运行时才知道。因此,只能在运行时评估结果函数调用。

答案 2 :(得分:0)

  

因此,如何理解constexpr功能有其所需的一切&#34;至   在编译时计算它的结果?

链接中的这一行引用 [1]

constexpr int add(int a, int b)  
{
    return a + b;
}

static constexpr int val = add(3, 4); // [1] here

add()有两个参数,即文字。

这些值在编译时已知,34

  

但根据我的理解,对于第一种情况,argc值也是如此   在编译时不可知,其值应该是   运行时间,对吗?

在编译期间无法知道其值的变量或参数仍可用作constexpr函数的参数。 As long as the parameter type is a literal type