问题
Is there any other difference between throw()
and noexcept
apart from being checked runtime and compile time respectively ?
Wikipedia C++11 article suggests that C++03 throw specifiers are deprecated.
Why so, is noexcept
capable enough to cover all that at compile time ?
[Note: I referred this question and this article, but couldn\'t got the solid reason of deprecation.]
回答1:
Exception specifiers were deprecated because exception specifiers are generally a terrible idea. noexcept
was added because it's the one reasonably useful use of an exception specifier: knowing when a function won't throw an exception. Thus it becomes a binary choice: functions that will throw and functions that won't throw.
noexcept
was added rather than just removing all throw specifiers other than throw()
because noexcept
is more powerful. noexcept
can have a parameter which compile-time resolves into a boolean. If the boolean is true, then the noexcept
sticks. If the boolean is false, then the noexcept
doesn't stick and the function may throw.
Thus, you can do something like this:
struct<typename T>
{
void CreateOtherClass() { T t{}; }
};
Does CreateOtherClass
throw exceptions? It might, if T
's default constructor can. How do we tell? Like this:
struct<typename T>
{
void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};
Thus, CreateOtherClass()
will throw iff the given type's default constructor throws. This fixes one of the major problems with exception specifiers: their inability to propagate up the call stack.
You can't do this with throw()
.
回答2:
noexcept
isn't checked at compile time.
An implementation shall not reject an expression merely because when executed it throws or might throw an exception that the containing function does not allow.
When a function that is declared noexcept
or throw()
attempts to throw an exception the only difference is that one calls terminate
and the othe calls unexpected
and the latter style of exception handling has effectively been deprecated.
回答3:
std::unexpected() is called by the C++ runtime when a dynamic exception specification is violated: an exception is thrown from a function whose exception specification forbids exceptions of this type.
std::unexpected() may also be called directly from the program.
In either case, std::unexpected calls the currently installed std::unexpected_handler. The default std::unexpected_handler calls std::terminate.
来源:https://stackoverflow.com/questions/12833241/difference-between-c03-throw-specifier-c11-noexcept