Các mã chỉ định ngoại lệ không được dùng nữa vì các mã chỉ định ngoại lệ nói chung là một ý tưởng tồi . noexcept
đã được thêm vào bởi vì đó là một cách sử dụng hợp lý hữu ích của bộ chỉ định ngoại lệ: biết khi nào một hàm không đưa ra ngoại lệ. Do đó, nó trở thành một lựa chọn nhị phân: các hàm sẽ ném và các hàm sẽ không ném.
noexcept
đã được thêm vào thay vì chỉ xóa tất cả các chỉ số ném ngoài throw()
bởi vì noexcept
nó mạnh hơn. noexcept
có thể có một tham số mà thời gian biên dịch phân giải thành một boolean. Nếu boolean là true, thì đúng 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ư sau:
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Làm CreateOtherClass
ném ngoại lệ không? Nó có thể, nếu hàm tạo T
mặc định của có thể. Làm thế nào để chúng tôi 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 hàm tạo mặc định của kiểu đã cho. Điều này khắc phục một trong những vấn đề lớn với các chỉ định ngoại lệ: chúng không có khả năng truyền lên ngăn xếp cuộc gọi.
Bạn không thể làm điều này với throw()
.
noexcept
có thể phải kiểm tra thời gian chạy. Sự khác biệt chính giữa chúng là phá vỡnoexcept
gây rastd::terminate
trong khi phá vỡthrow
nguyên nhânstd::unexpected
. Cũng là một hành vi mở ngăn xếp hơi khác trong những trường hợp này.