Giới thiệu
Trong C++20, hai tính năng consteval và constexpr được sử dụng để chỉ ra rằng một hàm hoặc biểu thức có thể được tính toán tại thời điểm biên dịch (compile -time). Tuy nhiên, mỗi từ khóa lại có những điểm khác biệt quan trọng.
Từ khóa consteval là gì?
consteval là một từ khóa mới được giới thiệu trong C++20. Khi khai báo một hàm với consteval, bạn bắt buộc phải tính giá trị trả về của hàm ngay tại thời điểm biên dịch. Điều này biến hàm thành một immediate function — nếu hàm không được tính toán tại thời điểm biên dịch thì quá trình biên dịch sẽ báo lỗi. Kết quả luôn được xác định tại compile -time.
Từ khóa constexpr là gì?
constexpr đã xuất hiện từ C++11 và được cải tiến qua nhiều phiên bản. Các hàm constexpr có thể (nhưng không bắt buộc) được tính toán tại thời điểm biên dịch. Nếu trình biên dịch có đủ thông tin, nó sẽ thực hiện tính toán tại compile -time; ngược lại, hàm vẫn có thể thực thi bình thường tại runtime. Do đó constexpr linh hoạt hơn và có thể sử dụng trong cả ngữ cảnh compile -time và runtime.
So sánh consteval và constexpr
- Thời điểm giới thiệu:
constevallần đầu xuất hiện trong C++20, trong khiconstexprđã có từ C++11. - Yêu cầu đánh giá:
constevalyêu cầu hàm luôn được đánh giá tại thời điểm biên dịch;constexprchỉ khuyến khích, nhưng không bắt buộc. - Hành vi khi không thể đánh giá: Với
consteval, nếu hàm không thể tính toán tại compile -time thì trình biên dịch sẽ trả về lỗi.constexprsẽ rơi về tính toán tại runtime trong trường hợp này. - Phạm vi sử dụng:
constevalthích hợp khi bạn muốn đảm bảo kết quả tại compile -time;constexprphù hợp cho các trường hợp linh hoạt hơn.
Ví dụ minh họa
Dưới đây là ví dụ về cách sử dụng hai từ khóa này:
// Hàm consteval — bắt buộc tính toán lúc biên dịch
consteval int square(int n) {
return n * n;
}
// Hàm constexpr — có thể tính toán lúc biên dịch hoặc runtime
constexpr int cube(int n) {
return n * n * n;
}
void example() {
constexpr int a = 5;
// OK – square được tính tại thời điểm biên dịch với giá trị hằng
int b = square(a);
// Lỗi – square phải được tính tại thời điểm biên dịch
// nhưng input_value là giá trị runtime
int input_value = get_user_input();
int c = square(input_value); // lỗi biên dịch!
// OK – cube có thể được tính tại runtime
int d = cube(input_value);
}
```
## Kết luận
`consteval` và `constexpr` đều là các công cụ mạnh mẽ giúc tối ưu chương trình C++ bằng cách tính toán giá trị tại thời điểm biên dịch. Sử dụng `consteval` khi bạn cần một hàm luôn được đánh giá tại compile -time, và dùng `constexpr` cho các trường hợp linh hoạt hơn.