1. Vấn đề nó giải quyết
C++23 bỏ một số giới hạn nhân tạo trong thân hàm constexpr. Nhiều mã trông bình thường hơn có thể khai báo constexpr, nhưng chỉ đường đi hợp lệ mới được chạy lúc biên dịch.
2. Kiến thức cần có
Ngày 7: ngữ cảnh constant evaluation và
if consteval.Biến và hàm
constexprcơ bản.
3. Ý tưởng cốt lõi
Hàm constexpr là công cụ dùng được ở hai thời điểm, không phải lời hứa mọi lời gọi đều ở compile time. C++23 cho phép thêm cấu trúc nhưng bộ đánh giá vẫn kiểm tra đường đi thực tế. Hãy xác định giá trị đang được biến đổi rồi kiểm tra kiểu, lifetime hoặc quyền sở hữu kết quả. Bật C++23 chưa chắc thư viện đã triển khai đủ, vì vậy cần kiểm tra feature-test macro liên quan.
4. Cú pháp tối thiểu
constexpr int value() { static constexpr int n = 7; return n; }5. Cách nó hoạt động
Ví dụ tạo biểu thức hoặc đối tượng nhỏ nhất cho Các mở rộng
constexprtrong C++23.Chương trình dùng hằng static được C++23 cho phép trong hàm
constexprkhi compiler hỗ trợ.Cuối cùng, nó in hoặc kiểm tra giá trị được chứng minh bằng
static_asserthoặc thông báo hỗ trợ rõ ràng trên toolchain này để dễ đối chiếu.
6. Lỗi thường gặp
Cho rằng mọi câu lệnh trong hàm
constexprđều chạy được lúc tính hằng là nhầm giữa quy tắc khai báo và quy tắc đánh giá.Không kiểm tra feature-test macro có thể chọn nhánh mã thư viện hiện tại chưa hỗ trợ.
7. Khi nào nên dùng
Nên dùng khi thuật toán cần chạy cả lúc biên dịch lẫn runtime bằng một thân hàm dễ đọc.
Tránh dùng khi ép khối lượng lớn vào compile time khi chỉ làm build chậm mà không tăng độ đúng.
8. Ví dụ đơn giản
Phép tính kích thước bảng nhỏ được kiểm tra lúc biên dịch rồi tái sử dụng ở runtime. Chương trình dùng dữ liệu cố định để output dễ kiểm tra.
Mã mẫu hoàn chỉnh
Tệp mã nguồn
cpp23/08_constexpr_extensions/main.cpp
#include <iostream>
#if defined(__cpp_constexpr) && __cpp_constexpr >= 202211L
constexpr int cached_value() {
// Static constexpr locals became usable here in C++23.
static constexpr int value = 7;
return value;
}
#endif
int main() {
#if defined(__cpp_constexpr) && __cpp_constexpr >= 202211L
constexpr int value = cached_value();
static_assert(value == 7);
std::cout << "value=" << value << '\n';
#else
std::cout << "C++23 constexpr extension unavailable\n";
#endif
}
9. Điều cần nhớ
Tách quy tắc chuẩn khỏi mức hỗ trợ thực tế.
Làm rõ lifetime, ownership và kiểu suy luận.
Ưu tiên cú pháp ngắn, đúng ý định.
Guard tính năng chưa được hỗ trợ đồng đều.
10. Câu hỏi tự kiểm tra
Dễ — Cú pháp ngắn nhất ở Phần 4 là gì và nhiệm vụ chính của nó là gì?
Trung bình — Đọc chương trình mẫu: giá trị, kiểu hoặc nhánh nào được quan sát, và vì sao?
Khó — Vì sao hàm
constexprcó thể chứa cấu trúc làm một đường đi không phải constant expression nhưng đường khác vẫn thành công?