không có điều này có thể không phải là trường hợp, bởi vì không phải mọi inovocation chức năng constexpr có để có thể được đánh giá là biểu hiện của một biểu thức liên tục lõi. Chúng tôi chỉ cần một giá trị đối số cho phép điều này. Vì vậy, một hàm constexpr có thể chứa một câu lệnh ném miễn là chúng ta có một giá trị đối số không gọi nhánh đó.
này được đề cập trong dự thảo C++ 14 phần chuẩn 7.1.5
Các constexpr specifier [dcl.constexpr] mà cho chúng ta biết những gì được cho phép trong một hàm constexpr:
Định nghĩa của một hàm constexpr phải đáp ứng các ràng buộc sau:
không được ảo (10.3);
loại trả về phải là loại chữ;
mỗi loại tham số của nó phải là một loại chữ;
nó chức năng thân phải = xóa, = mặc định, hoặc một hợp chất-tuyên bố rằng không chứa
mà như chúng ta có thể thấy không cấm throw
và trong thực tế cấm rất ít kể từ đề nghị Relaxing constraints on constexpr functions trở thành một phần của C++ 14.
Dưới đây chúng ta thấy các quy tắc mà nói một hàm constexpr là tốt được hình thành nếu ít nhất một giá trị đối số tồn tại như vậy mà nó có thể được đánh giá là một subexpression của một biểu thức hằng lõi:
Đối với một phi mẫu, chức năng constexpr không được mặc định hoặc không thừa kế, không thừa kế, không kế thừa constructor constexpr, nếu không có giá trị đối số tồn tại sao cho yêu cầu hàm hoặc hàm tạo có thể là biểu thức con được đánh giá. (5.19), chương trình bị lỗi hình thành; không yêu cầu chẩn đoán .
và dưới đoạn này chúng ta có ví dụ sau, trong đó cho thấy một ví dụ hoàn hảo cho trường hợp này:
constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
Vì vậy, chúng tôi mong chờ các đầu ra cho các ví dụ sau:
#include <iostream>
constexpr int f(bool b) { return b ? throw 0 : 0; }
int main() {
std::cout << noexcept(f(1)) << "\n"
<< noexcept(f(0)) << "\n" ;
}
trở thành (see it live with gcc):
0
1
Visual Studio qua webcompiler cũng tạo ra kết quả tương tự. Như hvd lưu ý, clang có lỗi như được ghi trong báo cáo lỗi noexcept should check whether the expression is a constant expression.
Defect Báo cáo 1129
Defect report 1129: Default nothrow for constexpr functions hỏi cùng một câu hỏi:
Một chức năng constexpr không được phép trở lại thông qua một ngoại lệ.Điều này cần được công nhận, và một hàm được khai báo constexpr mà không có một đặc tả ngoại lệ rõ ràng nên được xử lý như thể khai báo noexcept (true) chứ không phải là thông thường noexcept (false). Đối với một mẫu hàm được khai báo constexpr không có một đặc tả ngoại lệ rõ ràng, nó phải được coi là noexcept (true) nếu và chỉ khi từ khóa constexpr được tôn trọng trên một instantiation đã cho.
và phản ứng là:
Những tiền đề là không đúng: một ngoại lệ bị cấm chỉ khi một chức năng constexpr được gọi trong một bối cảnh mà đòi hỏi một biểu thức hằng. Được sử dụng như một chức năng bình thường, nó có thể ném.
và nó biến đổi 5.3.7 [expr.unary.noexcept] đoạn 3 viên đạn 1 (Ngoài ra lưu ý với sự nhấn mạnh):
một call80 có khả năng đánh giá cho một hàm, hàm thành viên, chức năng con trỏ, hoặc thành viên con trỏ hàm mà không có một tổ chức phi ném ngoại lệ đặc điểm kỹ thuật (15,4 [except.spec]), trừ khi cuộc gọi là một biểu thức hằng số (5,20 [expr.const]),
@ cad anyways t câu hỏi của anh ta rất chung chung, đừng nghĩ rằng có ví dụ cụ thể tốt. – Orient
Ví dụ truy cập: 'constexpr void * foo (int n) {return n == 0? nullptr: toán tử new (n); } '. [Demo] (https://ideone.com/zlTsDI). –
Tôi đã lạm dụng điều này một lần, xem http://stackoverflow.com/a/13305072/34509 –