Mộc Viên's Blog Mộc Viên's Blog
Consteval vs constexpr trong C++20: Giải thích và ví dụ minh họa

Consteval vs constexpr trong C++20: Giải thích và ví dụ minh họa

Ngày đăng:

Consteval vs constexpr trong C++20: Giải thích và ví dụ minh họa

Giới thiệu

Trong C++20, hai tính năng constevalconstexpr đượ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 constevalconstexpr

  • Thời điểm giới thiệu: consteval lần đầu xuất hiện trong C++20, trong khi constexpr đã có từ C++11.
  • Yêu cầu đánh giá: consteval yêu cầu hàm luôn được đánh giá tại thời điểm biên dịch; constexpr chỉ 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. constexpr sẽ rơi về tính toán tại runtime trong trường hợp này.
  • Phạm vi sử dụng: consteval thích hợp khi bạn muốn đảm bảo kết quả tại compile -time; constexpr phù 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.

Gần đây