C++11 增加了constexpr关键字,同const关键字相比,constexpr关键字不仅可以修饰变量和指针,而且可以修饰一个函数.
constexpr修饰变量的时候,同const类似:声明时必须初始化,并且变量的值后续不能被修改.
#include <iostream>
using namespace std;
int main(void) {
constexpr int a = 2;
constexpr int b = a + 4;
std::cout << "a=" << a << endl;
std::cout << "b=" << b << endl;
int c = 10;
constexpr int d = c; // error: c is not const
return 0;
}
constexpr修饰指针的时候,同const相比,有一点不同:const放在*号前,表示指针指向的内容不能被修改.const放在*号后,表示指针不能被修改.*号前后都有const关键字表示指针和指向的内容都不能被修改;constexpr关键字只能放在*号前面,并且表示指针的内容不能被修改:
#include <iostream>
using namespace std;
int count = 10;
int main(void) {
constexpr int *ptr1 = &count;
int constexpr *ptr2 = &count;
*ptr1 = 20;
cout << *ptr1 << std::endl;
cout << *ptr2 << std::endl;
return 0;
}
如下编译不通过:
(1) int c = 20;
constexpr int *ptr = &c; // error: c在栈上分配,c的地址不能在编译时确定
(2)constexpr int *ptr = &g_count;
ptr = nullptr; // error: ptr是constexpr修饰的,不能被修改
*ptr = 100; // ok: 值可以被修改
constexpr修饰函数的时候,表示该函数既可以作为常量表达式(在编译时确定返回值),也可以作为普通函数(运行时确定返回值).如果函数返回值赋值给constexpr变量,则在编译时确定返回值;如果函数返回值赋值给普通变量,则在运行时确定返回值:
#include <iostream>
using namespace std;
constexpr int func(int count) {
return count + 2;
}
int main(void) {
constexpr int count1 = func(2);
int count2 = func(4);
cout << count1 << endl;
cout << count2 << endl;
return 0;
}
当然,constexpr修饰的函数也有一定的限制:
(1)函数体只能包含一个return语句;
(2)函数体可以包含其他语句,但是不能是运行期语句,只能是编译期语句;
#include <iostream>
using namespace std;
#define MAX 10
constexpr int func(int count) {
#ifdef MAX
return count + 2;
#else
return 0;
#endif
}
int main(void) {
constexpr int count1 = func(2);
int count2 = func(4);
cout << count1 << endl;
cout << count2 << endl;
return 0;
}