2012-10-11 59 views
78

Có sự khác biệt nào khác giữa thời gian chạy thử và thời gian biên dịch lần lượt là throw()noexcept không?Sự khác biệt giữa C++ 03 throw() specifier C++ 11 noexcept

Wikipedia C++11 bài viết gợi ý rằng trình chỉ định ném C++ 03 không được dùng nữa.
Tại sao vậy, là noexcept đủ khả năng để trang trải tất cả những gì tại thời gian biên dịch?

[Lưu ý: Tôi gọi this questionthis article, nhưng không thể có lý do vững chắc của deprecation.]

+6

Accodring [this article] (http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/) cũng 'noexcept' có thể phát sinh kiểm tra thời gian chạy. Sự khác biệt chính giữa chúng là việc phá vỡ 'noexcept' gây ra' std :: terminate' trong khi phá vỡ 'throw' gây ra' std :: unexpected'. Ngoài ra một hành vi thư giãn ngăn xếp hơi khác nhau trong những trường hợp này. – Fiktik

Trả lời

101

specifiers ngoại lệ được phản vì exception specifiers are generally a terrible idea. noexcept đã được thêm vì đó là cách sử dụng hợp lý một thông số ngoại lệ hữu ích: biết khi nào một hàm sẽ không ném một ngoại lệ. Vì vậy, nó trở thành một sự lựa chọn nhị phân: các chức năng sẽ ném và các chức năng mà sẽ không ném.

noexcept đã được thêm thay vì chỉ xóa tất cả các thông số ném khác ngoài throw()noexcept mạnh hơn. noexcept có thể có tham số mà thời gian biên dịch phân giải thành boolean. Nếu boolean là true, thì các gậy noexcept. Nếu boolean là false, thì noexcept không dính và hàm có thể ném.

Vì vậy, bạn có thể làm một cái gì đó như thế này:

struct<typename T> 
{ 
    void CreateOtherClass() { T t{}; } 
}; 

Liệu CreateOtherClass ngoại lệ ném? Có thể, nếu hàm tạo mặc định của T có thể. Làm thế nào để chúng ta nói? Như thế này:

struct<typename T> 
{ 
    void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } 
}; 

Do đó, CreateOtherClass() sẽ ném iff của trình tạo mặc định của loại đã cho. Điều này khắc phục một trong những vấn đề lớn với các specifier ngoại lệ: không có khả năng truyền bá stack call.

Bạn không thể thực hiện việc này với throw().

+0

+1 Câu trả lời hữu ích, dù sao đi nữa. Vẫn đang tìm kiếm câu trả lời cho biết tại sao tôi muốn sử dụng 'noexcept'. Tôi không bao giờ sử dụng 'throw()' specifier, bao giờ và đang cố gắng để xác định nếu 'noexcept' thực sự cung cấp bất kỳ lợi ích nào (ngoài tài liệu kiểm tra trình biên dịch). – hmjd

+0

Chỉ tìm thấy http://stackoverflow.com/questions/10787766/when-should-i-really-use-noexcept ... – hmjd

+0

@hmjd: "* Vẫn đang tìm kiếm câu trả lời cho biết lý do tôi muốn sử dụng noexcept . * "Bạn sẽ không tìm thấy câu trả lời ở đây vì đó là * không phải là câu hỏi * được hỏi. –

29

noexcept không được chọn lúc biên dịch.

Việc triển khai sẽ không từ chối biểu thức chỉ vì khi thực thi nó ném hoặc có thể ném ngoại lệ mà chức năng chứa không cho phép.

Khi một hàm được khai báo noexcept hoặc throw() nỗ lực để ném một ngoại lệ khác biệt duy nhất là ai gọi terminate và các cuộc gọi Othe unexpected và phong cách sau xử lý ngoại lệ đã có hiệu quả được phản đối.

1

std :: unexpected() được gọi bởi thời gian chạy C++ khi đặc tả ngoại lệ động bị vi phạm: ngoại lệ được ném từ hàm có đặc tả ngoại lệ cấm ngoại lệ của loại này.

std :: unexpected() cũng có thể được gọi trực tiếp từ chương trình.

Trong cả hai trường hợp, std :: unexpected calls std hiện tại được cài đặt :: unexpected_handler. Mặc định std :: unexpected_handler gọi std :: chấm dứt.

Các vấn đề liên quan