2011-12-24 37 views
44

Làm cách nào để thực hiện đúng cách static_assert trong một chức năng constexpr? Ví dụ:C++ 11 - static_assert trong hàm constexpr?

constexpr int do_something(int x) 
{ 
    static_assert(x > 0, "x must be > 0"); 
    return x + 5; 
} 

Đây không phải là mã C++ 11 hợp lệ, vì hàm constexpr chỉ được chứa câu lệnh trả về. Tôi không nghĩ rằng tiêu chuẩn có ngoại lệ cho điều này, mặc dù, GCC 4.7 không cho phép tôi biên dịch mã này.

Trả lời

52

Đây không phải là mã C++ 11 hợp lệ, vì hàm constexpr chỉ được chứa câu lệnh trả về.

Điều này không đúng. static_assert trong một chức năng constexpr là tốt. không phải là Phạt tiền là sử dụng các tham số hàm trong biểu thức hằng số, giống như bạn làm điều đó.

Bạn có thể ném nếu x <= 0. Gọi hàm trong một bối cảnh đó đòi hỏi một biểu thức hằng số sau đó sẽ thất bại trong việc biên dịch

constexpr int do_something(int x) { 
    return x > 0 ? (x + 5) : (throw std::logic_error("x must be > 0")); 
} 
+9

Cool, tôi không biết 'throw's trong một' chức năng constexpr' đó được gọi là trong một bối cảnh constexpr sẽ khiến quá trình biên dịch thất bại! – Xeo

+16

@Xeo đang làm * mọi thứ * không biểu hiện ở phía bên kia?: Sẽ thực hiện công việc. :) –

+0

Bổ sung tốt cho 'static_assert' tôi phải nói. :) – Xeo

20

này hoạt động và có giá trị mã C++ 11, bởi vì đối số mẫu là thời gian biên dịch chỉ:

template <int x> 
constexpr int do_something() { 
    static_assert(x > 0, "x must be > 0"); 
    return x + 5; 
} 

tôi phải đối mặt với các vấn đề tương tự như bạn đã làm với các biểu thức liên tục trong C++. Có ít tài liệu rõ ràng về constexprs tại thời điểm này. Và lưu ý rằng có một số lỗi đã biết với nó trong trình theo dõi vấn đề của gcc, nhưng vấn đề của bạn có vẻ không phải là một lỗi.

Lưu ý rằng nếu bạn khai báo hàm constexpr bên trong các lớp, bạn không thể sử dụng chúng trong lớp. Điều này cũng có vẻ không phải là một lỗi.

Chỉnh sửa: Đây là phép theo tiêu chuẩn: 7.1.3 bang

... hoặc một hợp chất-tuyên bố rằng chỉ chứa

  • báo cáo null,
  • static_assert -declarations
  • khai báo typedef và khai báo bí danh không
    xác định các lớp hoặc bảng liệt kê,
  • sử dụng-khai,
  • sử dụng-chỉ thị,
  • và chính xác một sự trở lại tuyên bố
+1

Không. Constexpr phải chỉ là một câu lệnh trả về đơn. –

+1

Thật sao? Nó làm việc cho tôi. Tôi đang làm gì sai? http://ideone.com/3GOk7Q – cppist

+1

Tôi đọc tiêu chuẩn. Bạn là chính xác, điều này là tốt. Tôi đã chỉnh sửa câu trả lời của bạn để thêm câu trả lời đó. –