2015-10-13 98 views
2

所以一般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是右值,但也没办法(我猜),他们可以强制转换为constexpr(如果我们可以一般地说关于铸造到constexpr),所以我认为它会在运行时执行。但是,在编译时间内x和y都是已知的,因此在运行时没有实际的理由来执行它。

所以我的问题是它是如何在现实生活中?将这个函数在运行时被执行或编译时

+4

文字也是不变的表达。 –

+0

如果是这样,请将其作为回答发布,我将接受它:) – DawidPi

+0

如果优化程序在编译时也可能会调用带有非常量“x”和“y”的调用'function(x,y)'意识到'x'和'y'将始终具有相同的值。它不需要这样做,并且在需要'constexpr'的地方不能使用结果。 –

回答

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

TL;博士

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

东西... 我有一个快速查看标准,我希望我没有错过任何重要的观点。

我们已经知道从@ 42的回答是:

  • 据N4527 int是一个constexpr功能有效的放慢参数类型,因为它是一个文本类型(因为它是一个标量类型,是由同一文档的一个3.9/10字面类型)。因此,fun是一个有效的constexpr函数。

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

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

§5.20从N4527说:

甲条件表达式e是一个芯常量表达式除非e的评价,如下所述抽象机(1.9)的规定,将评估的一个下面的表达式:

  • 这里来的东西,阻止核常量表达式
表达式的大名单

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

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

两个56整数常量int类型的按§2.13.2

1)的整数文字是不具有周期或指数部分数字序列,可选的分离单在确定其价值时被忽略的引号。 [...]

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

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

现在看看§5.20再次我们看到:这两个是常量表达式。

+0

“因此,如果5和6是常量表达式,那么fun(5,6)是一个常量表达式,如果fun声明为constexpr并且在使用它之前被定义。 ......不知道你必须知道在它的身体里做了些什么“乐趣”来作出判断 - 检查[this](http://stackoverflow.com/q/23775705/2352671)。你已经结束了一个简单的问题 – 101010

+0

@ 101010是的,该函数必须是一个有效的constexpr函数。 – Pixelchemist

2

根据该草案标准N45277.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编译失败。

+0

酷我不知道,谢谢 – DawidPi

+2

“它是有效/保证,因为它编译”不是一个很好的论点。可能是编译器扩展,编译器错误或其他。 – Pixelchemist

+0

@Pixelchemist'std :: integral_constant'不是编译器扩展。它在标准[20.10.2标题摘要[meta.type.synop] ]。 – 101010