constexpr函数和硬编码参数

时间:2015-10-13 06:53:36

标签: c++ c++11 constexpr

因此,通常constexpr函数是在编译时执行的函数,当传递给它的参数也是constexpr时,如下所示:

constexpr int function(int x, int y){
   return x+y;
}

参数声明如下:

constexpr int x = 5;
constexpr int y = 6;

将在编译时执行,但使用以下参数声明:

int x=5;
int y=6;

不会。我想知道如果我们以下列方式调用此函数会发生什么:

function(5,6);

从技术角度来看,5和6是rvalues,但我们没有办法(我猜),它们可以被铸造到constexpr(如果我们可以说通常关于铸造到constexpr),所以在我看来它会被执行在运行时中。但是,没有实际的理由在运行时执行它,因为在编译期间x和y都是已知的。

所以我的问题是现实生活中的情况如何?此函数是在运行时还是编译时执行

2 个答案:

答案 0 :(得分:2)

根据标准草案N4527 7.1.5 / 3 constexpr说明符[dcl.constexpr] 强调我的):

  

constexpr函数的定义应满足以下条件   约束:

     

(3.1) - 它不应是虚拟的(10.3);

     

(3.2) - 其返回类型应为文字类型;

     

(3.3) - 每个参数类型都应为文字类型;

     

...

因此,调用function(5,6);满足constexpr函数的定义,执行将在编译时执行。

此外,您可以使用std::integral_constant

自行测试
#include <iostream>
#include <type_traits>

constexpr int fun(int x, int y) {
   return x + y;
}

int main() {
    std::cout << std::integral_constant<int, fun(5, 6)>::value << std::endl;
}

LIVE DEMO

如果fun中的输入参数不是constexpr,则编译将失败。

答案 1 :(得分:2)

constexpr int fun(int x, int y) { return x+y; }
fun(5,6) // << constant expression?

tl; dr

56是常量表达式。因此fun(5,6)也是一个常量表达式,将在编译时进行求值,这是必需的(例如非类型模板)。

<强>东西... 我快速浏览了标准,希望我没有错过任何重要的观点。

我们已经从@ 42的答案中得知:

  • 根据N4527 int constexpr函数的有效参数类型,因为它是一个文字类型(因为它是一个标量类型,是§3.9/ 10同一文件的文字类型)。因此,fun是一个有效的constexpr函数。

  • 它提供的代码将fun(5,6)置于需要常量表达式的上下文中,并且似乎被某些编译器接受。

现在的问题是这是否是有效的,符合标准的行为。

来自N4527的

§5.20说:

  

条件表达式e是核心常量表达式,除非根据抽象机器(1.9)的规则评估e将评估以下表达式之一:

     
      
  • 这里列出了阻止表达式成为核心常量表达式的大量事项
  •   

该列表不包含“具有常量表达式参数的constexpr函数”,因此它们是核心常量表达式(除非它们在使用时未定义)。

因此,如果56是常量表达式,那么fun(5,6)是一个常量表达式,如果fun是有效的 constexpr函数并且在使用之前定义。给定的函数满足§7.1.5/ 3中的要求约束,并且是一个有效的 constexpr函数

根据§2.13.2

56都是类型int整数文字
  

1)整数文字是一个没有句号或指数部分的数字序列,可选的分隔单引号在确定其值时被忽略。 [...]

     

2)整数文字的类型是表5中相应列表中第一个可以表示其值的列表。

     

后缀:none,十进制文字:intlong intlong long int

现在再次看§5.20,我们看到:两者都是常数表达式。