C++11新特性 3.constexpr
目录
一.简介
1.基本概念
2.语法
(1)constexpr 变量
(2)constexpr 函数
二.使用示例
示例1:constexpr 修饰变量
示例2:constexpr 修饰函数
示例3:constexpr 修饰构造函数
三.注意事项
1.constexpr 的使用限制
2.constexpr 的优势
3.const和constexpr的区别
一.简介
1.基本概念
constexpr是 C++11 引入的一个关键字,用于声明常量表达式。常量表达式是在编译时就能计算出结果的表达式,使用 constexpr 可以让编译器在编译阶段进行计算,提高程序的性能和安全性。
在 C++ 中,有些地方要求使用常量表达式,比如数组的大小、枚举值、模板参数等。constexpr 可以让我们定义编译时常量,使得代码更加清晰和高效。
2.语法
(1)constexpr 变量
constexpr 类型 变量名 = 常量表达式;
变量的初始化必须使用常量表达式,这样编译器才能在编译时确定其值。
(2)constexpr 函数
constexpr 返回类型 函数名(参数列表) {// 函数体
}
constexpr函数的函数体必须满足一定的条件,例如只能包含 return 语句,并且返回值必须是常量表达式。
二.使用示例
示例1:constexpr 修饰变量
当 constexpr 用于修饰变量时,它表明该变量是一个常量表达式,其值必须在编译时确定。
#include <iostream>// 定义一个 constexpr 变量
constexpr int num = 10;// 可以在编译时使用该变量
constexpr int square = num * num;int main() {std::cout << "The square of " << num << " is " << square << std::endl;return 0;
}
在上述代码中,num 被声明为 constexpr 变量,其值在编译时就确定为 10。square 同样是 constexpr 变量,它的值是 num * num 的结果,也在编译时计算得出。
示例2:constexpr 修饰函数
当 constexpr 用于修饰函数时,函数必须要有返回值,且return返回值必须是常量表达式。
该函数可以在编译时被调用,前提是传入的参数是常量表达式。
#include <iostream>// 定义一个 constexpr 函数
constexpr int add(int a, int b) {return a + b;
}int main() {// 在编译时调用 constexpr 函数constexpr int result = add(3, 5);std::cout << "The result of 3 + 5 is " << result << std::endl;int x = 3;int y = 5;// 运行时调用 constexpr 函数int runtimeResult = add(x, y);std::cout << "The result of x + y is " << runtimeResult << std::endl;return 0;
}
在这个例子中,add 函数被声明为 constexpr 函数。当传入的参数 3 和 5 是常量表达式时,add 函数会在编译时被调用,result 的值在编译时就确定了。而当传入的参数是变量 x 和 y 时,add 函数会在运行时被调用。
示例3:constexpr 修饰构造函数
constexpr 也可以用于修饰构造函数,这样的构造函数可以在编译时创建对象。
#include <iostream>// 定义一个类
class Point {
public:// 定义 constexpr 构造函数//必须是空实现,初始化在 :后的列表里constexpr Point(int x, int y) : x_(x), y_(y) {}// 定义 constexpr 成员函数constexpr int getX() const { return x_; }constexpr int getY() const { return y_; }private:int x_;int y_;
};int main() {// 在编译时创建对象constexpr Point p(2, 3);// 在编译时调用 constexpr 成员函数constexpr int x = p.getX();constexpr int y = p.getY();std::cout << "Point: (" << x << ", " << y << ")" << std::endl;return 0;
}
在上述代码中,Point 类的构造函数被声明为 constexpr 构造函数,这样就可以在编译时创建 Point 对象。getX 和 getY 成员函数也被声明为 constexpr 函数,它们可以在编译时被调用。
三.注意事项
1.constexpr 的使用限制
(1)constexpr 函数:
1.函数体必须足够简单,只能包含
return语句,不能包含复杂的控制结构(如while、for等),但在 C++14 及以后版本有所放宽,允许使用更复杂的语句。2.函数的返回值类型和参数类型必须是字面类型(如基本数据类型、枚举类型、具有
constexpr构造函数的类等)。
(2)constexpr 构造函数:
1.构造函数体必须为空,或者只包含
static_assert、typedef、using等不影响对象初始化的语句。2.必须初始化所有成员变量。
2.constexpr 的优势
(1)性能提升:由于常量表达式在编译时计算,避免了运行时的计算开销,提高了程序的执行效率。
(2)代码安全性:使用
constexpr可以确保变量和函数的结果在编译时确定,减少了运行时错误的可能性。(3)模板元编程:
constexpr在模板元编程中非常有用,可以在编译时进行复杂的计算和类型推导。
3.const和constexpr的区别
(1)const
const 关键字主要用于声明一个只读变量,它强调的是运行时的常量性,即一旦变量被初始化后,在程序运行期间其值不能被修改。
可以用于修饰普通变量、函数参数、函数返回值等,用于保证变量在运行时不会被意外修改。
(2)constexpr
constexpr 关键字用于声明常量表达式,它强调的是编译时的常量性,编译器会在编译阶段对 constexpr 修饰的表达式进行求值,生成一个编译时常量。
主要用于需要编译时常量的场景,如数组大小、枚举值、模板参数等。
