C++ consteval用法详解(附带实例)
在 C++ 中,如果函数的所有输入在编译时可用,那么 constexpr 函数允许在编译时进行函数运算。然而,这不是一定的,constexpr 函数也可能在运行时执行。
consteval 是 C++20 中引入的一个关键字,用于强制函数在编译期间计算,确保函数在编译时产生常量表达式
1) 定义必须在编译时运算的非成员函数或函数模板:
2) 定义必须在编译时执行的用来初始化 constexpr 对象的构造函数及只在编译时调用的成员函数:
即时函数有以下规则:
如何使用 factorial() 函数如下所示:
然而,以下示例会产生编译错误,因为即时函数 factorial() 和 point3d 的构造函数无法在编译时进行运算:
除非即时函数在常量表达式里,否则无法对其取地址:
consteval 是 C++20 中引入的一个关键字,用于强制函数在编译期间计算,确保函数在编译时产生常量表达式
C++ consteval的使用方式
使用 consteval 关键字,当你想要:1) 定义必须在编译时运算的非成员函数或函数模板:
constexpr unsigned int factorial(unsigned int const n)
{
return n > 1 ? n * factorial(n-1) : 1;
}
2) 定义必须在编译时执行的用来初始化 constexpr 对象的构造函数及只在编译时调用的成员函数:
class point3d
{
double x_;
double y_;
double z_;
public:
constexpr point3d(double const x = 0,
double const y = 0,
double const z = 0)
: x_{x}, y_{y}, z_{z}
{}
constexpr double get_x() const {return x_;}
constexpr double get_y() const {return y_;}
constexpr double get_z() const {return z_;}
};
深度剖析C++ consteval
consteval 说明符在 C++20 中引入。它只可用于函数或函数模板,并定义它们为即时函数。这意味着任何函数调用必须在编译时执行,并产生编译时常量表达式。如果函数不能在编译时进行运算,那么程序格式错误,编译器会报编译错误。即时函数有以下规则:
- 析构函数、分配、释放函数不能是即时函数;
- 如果函数声明包含 consteval 说明符,则所有那个函数的声明必须包含它;
- consteval 说明符不能和 constexpr 或 constinit 一起使用;
- 即时函数是内联 constexpr 函数。因此,即时函数和函数模板必须满足与 constexpr 函数相关的要求。
如何使用 factorial() 函数如下所示:
constexpr unsigned int f = factorial(6);
std::cout << f << '\n';
constexpr point3d p {0, 1, 2};
std::cout << p.get_x() << ' ' << p.get_y() << ' ' << p.get_z() << '\n';
然而,以下示例会产生编译错误,因为即时函数 factorial() 和 point3d 的构造函数无法在编译时进行运算:
unsigned int n;
std::cin >> n;
const unsigned int f2 = factorial(n); // error
double x = 0, y = 1, z = 2;
constexpr point3d p2 {x, y, z}; // error
除非即时函数在常量表达式里,否则无法对其取地址:
using pfact = unsigned int(unsigned int);
pfact* pf = factorial;
constexpr unsigned int f3 = pf(42); // error
constexpr auto addr_factorial()
{
return &factorial;
}
constexpr unsigned int invoke_factorial(unsigned int const n)
{
return addr_factorial()(n);
}
constexpr auto ptr = addr_factorial(); // ERROR: cannot take the pointer of an immediate function
constexpr unsigned int f2 = invoke_factorial(5); // OK
因为即时函数在运行时不可见,它们的符号没有生成,因此调试器无法显示它们。
ICP备案:
公安联网备案: