Giới thiệu
constexpr
đã không được giới thiệu như một cách để nói với việc thực hiện rằng một cái gì đó có thể được đánh giá trong bối cảnh đòi hỏi một biểu thức không đổi ; việc triển khai tuân thủ đã có thể chứng minh điều này trước C ++ 11.
Một cái gì đó mà việc thực hiện không thể chứng minh là ý định của một đoạn mã nhất định:
- Nhà phát triển muốn thể hiện điều gì với thực thể này?
- Chúng ta có nên mù quáng cho phép mã được sử dụng trong một biểu thức không đổi , chỉ vì nó xảy ra để làm việc?
Thế giới sẽ ra sao nếu không có constexpr
?
Giả sử bạn đang phát triển một thư viện và nhận ra rằng bạn muốn có thể tính tổng của mọi số nguyên trong khoảng (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
Sự thiếu ý định
Một trình biên dịch có thể dễ dàng chứng minh rằng hàm trên có thể gọi được trong một biểu thức không đổi nếu biết được đối số được truyền trong khi dịch; nhưng bạn đã không tuyên bố đây là một ý định - nó chỉ là trường hợp.
Bây giờ có người khác đến, đọc chức năng của bạn, thực hiện phân tích tương tự như trình biên dịch; " Ồ, chức năng này có thể sử dụng được trong một biểu thức không đổi!" và viết đoạn mã sau.
T arr[f(10)]; // freakin' magic
Tối ưu hóa
Bạn, với tư cách là một nhà phát triển thư viện "tuyệt vời" , quyết định rằng f
nên lưu trữ kết quả khi được gọi; Ai muốn tính toán cùng một tập hợp các giá trị?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
Kết quả
Bằng cách giới thiệu tối ưu hóa ngớ ngẩn của bạn, bạn vừa phá vỡ mọi cách sử dụng chức năng của mình trong một bối cảnh có biểu thức không đổi đòi hỏi phải có .
Bạn không bao giờ hứa rằng hàm này có thể sử dụng được trong một biểu thức không đổi , và nếu không constexpr
có cách nào sẽ cung cấp lời hứa như vậy.
Vậy, tại sao chúng ta cần constexpr
?
Việc sử dụng chính của constexpr là khai báo ý định .
Nếu một thực thể không được đánh dấu là constexpr
- nó không bao giờ được sử dụng trong một biểu thức không đổi ; và thậm chí nếu có, chúng tôi dựa vào trình biên dịch để chẩn đoán bối cảnh đó (vì nó coi thường ý định của chúng tôi).
constexpr
không? Nếu vậy, tôi có thể thấy một cách sử dụng.