【C++11】新特性——常量表达式constexpr

来源:互联网 发布:手机淘宝店招怎么设置 编辑:程序博客网 时间:2024/06/12 09:08
C++语言一直具有常量表达式的概念。这些诸如3+4之类的表达式总是产生相同的结果且不具备副作用。常量表达式给编译器带来了优化的可能,而编译器也经常在编译期执行此类表达式并将结果存放在程序中。此外,C++语言规范中有一些地方需要使用常量表达式。定义数组需要常量表达式,而枚举值也必须是常量表达式。
然而,每当碰到函数调用或对象构造,常量表达式便不再有效。所以简单如下例便不合法:
int GetFive()
{
return 5;
}
int some_value[GetFive() + 5]; //创建一个包含10个整型变量的数组,在标准C++中不合法
这段代码在C++中不合法,因为GetFive() + 5不是一个常量表达式。编译器无从知晓GetFive在运行期是否产生常量。理论上,这个函数可能会影响某个全局变量,或者调用其他运行期产生非常量的函数。
C++0x将引入constexpr关键字,此关键字将使用户能保证某个函数或构造器在编译期产生常量。上例可被改写如下:
constexpr int GetFive()
{
return 5;
}
int some_value[GetFive() + 5]; //在标准C++0x中合法
这段代码将使编译器理解并确认GetFive是个编译期常量。
在函数上使用constexpr将对函数功能施加严格的限制。首先,函数必须返回非void类型。其次,函数体必须具有"return /expr/"的形式。第三,expr在参数替换后必须是常量表达式。该常量表达式只能调用其他定义为constexpr的函数,只能使用其他常量表达式数据变量。第四,常量表达式中一切形式的递归均被禁止。最后,这种带constexpr的函数在编译单元中必须先定义后调用。
变量也可被定义为常量表达式值。
constexpr double forceOfGravity = 9.8;
constexpr double moonGravity = forceOfGravity / 6;
常量表达式数据变量隐含为常量。它们只能存放常量表达式或常量表达式构造器的结果。
为了从用户自定义类型中构建常量表达式数据值,构造器在声明时可带constexpr。同常量表达式函数一样,在编译单元中常量表达式构造器也必须先定义后使用。常量表达式构造器函数体必须为空,而且它必须用常量表达式构造其成员。这种类型的析构器必须是平凡的。
由常量表达式拷贝构造的类型也必须被定义为constexpr,以使它们能从常量表达式函数中作为值被返回。类的任何成员函数,包括拷贝构造器和操作符重载,都能被声明为constexpr,只要它们符合常量表达式函数的定义。这就允许编译器在编译期不仅能拷贝类对象,也能对其实施其他操作。
常量表达式函数或构造器可以用非constexpr参数来调用。就如同一个constexpr整数常量可以被赋给一个非constexpr变量一样,constexpr函数也可用非constexpr参数来调用,并且其结果也可存放在非constexpr变量中。此关键字只是提供了在一个表达式的全部成员均为constexpr时其结果为编译期常量的可能性。
0 0
原创粉丝点击