Is there any difference between throw()
and noexcept
other than being checked at runtime and compile time, respectively?
This Wikipedia C++11 article suggests that the C++03 throw specifiers are deprecated.
Why so, is noexcept
capable enough to cover all that at compile time ?
[Note: I checked this question and this article, but couldn't determine the solid reason for deprecation.]
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()
.