constexpr是C++ 11中添加的功能。主要思想是通过在编译时而非运行时进行计算来提高程序的性能。请注意,一旦程序由开发人员编译并完成,它将由用户多次运行。这个想法是要花时间在编译上并在运行时节省时间(类似于模板元编程)
constexpr指定可以在编译时评估对象或函数的值,并且该表达式可以在其他常量表达式中使用。例如,在下面的代码中,product()在编译时求值。
// constexpr function for product of two numbers.
// By specifying constexpr, we suggest compiler to
// to evaluate value at compile time
constexpr int product(int x, int y)
{
return (x * y);
}
int main()
{
const int x = product(10, 20);
cout << x;
return 0;
}
输出 :
200
一个函数声明为constexpr
- 在C++ 11中,constexpr函数应仅包含一个return语句。 C++ 14允许多个语句。
- constexpr函数应仅引用常量全局变量。
- constexpr函数只能调用其他constexpr函数,而不是简单函数。
- 函数不能为void类型,并且constexpr 函数不允许使用某些运算符,如前缀递增(++ v)。
constexpr与内联函数:
两者都是为了提高性能,内联函数要求编译器在编译时进行扩展并节省函数调用开销的时间。在内联函数中,表达式始终在运行时求值。 constexpr是不同的,这里的表达式是在编译时求值的。
constexpr提高性能的示例:
考虑下面的C++程序
// A C++ program to demonstrate the use of constexpr
#include
using namespace std;
constexpr long int fib(int n)
{
return (n <= 1)? n : fib(n-1) + fib(n-2);
}
int main ()
{
// value of res is computed at compile time.
const long int res = fib(30);
cout << res;
return 0;
}
当以上程序在GCC上运行时,需要0.003秒(我们可以使用time命令测量时间)
如果我们从下面的行中删除const,则在编译时不会评估fib(5)的值,因为constexpr的结果未在const表达式中使用。
Change,
const long int res = fib(30);
To,
long int res = fib(30);
进行上述更改后,程序花费的时间变得更高0.017秒。
具有构造函数的constexpr:
constexpr也可以在构造函数和对象中使用。有关可以使用constexpr的构造函数的所有限制,请参见此内容。
// C++ program to demonstrate uses of constexpr in constructor
#include
using namespace std;
// A class with constexpr constructor and function
class Rectangle
{
int _h, _w;
public:
// A constexpr constructor
constexpr Rectangle (int h, int w) : _h(h), _w(w) {}
constexpr int getArea () { return _h * _w; }
};
// driver program to test function
int main()
{
// Below object is initialized at compile time
constexpr Rectangle obj(10, 20);
cout << obj.getArea();
return 0;
}
输出 :
200
constexpr与const
它们有不同的用途。 constexpr主要用于优化,而const实际上用于const对象,例如Pi的值。
它们都可以应用于成员方法。将成员方法设为const,以确保该方法没有意外更改。另一方面,使用constexpr的想法是在编译时计算表达式,以便在运行代码时可以节省时间。
const只能与非静态成员函数一起使用,而constexpr可以与成员和非成员函数一起使用,即使与构造函数一起使用,但条件是参数和返回类型必须为字面量类型。