Is there any advantages or uses cases to throw other thing that a std::exception( or a derivatives types).
For example throw 1;
or throw \"error\";
Per §15.1 [except]:
Exception handling provides a way of transferring control and information from a point in the execution of a thread to an exception handler associated with a point previously passed by the execution.
The word information illustrates everything, it can be everything such as objects, numbers, ... .
There is nothing in standard that says you must just throw std::exception
. In the other words, maybe someone wants to throw his own exception objects.
Maybe someone wants to use exception-handling to handle something far from normal exceptions.
Yes, there can be advantages.
The most obvious is that the what
for existing derivatives of std::exception
(e.g., std::logic_error
, std::invalid_argument
) only deal with std::string
s or char *
s to specify the reason for the exception. That's probably fine if you only deal with an English speaking audience, but if you want to use the what
to display an error message to somebody who doesn't use English, it can get clumsy in a hurry.
If you're using (for example) 32-bit Unicode strings throughout your program, you'd typically prefer do the same in your exception handling. In such a case, a hierarchy similar to those in the standard, but using 32-bit Unicode strings for the what
argument probably makes a lot of sense. I suppose you could still use std::exception
for the base of that hierarchy, but it's open to question how much (if anything) you'd gain from doing so.
I can't think of any obvious reasons why a class derived from std::exception
wouldn't typically be better.
But the throw 1
or throw "Error"
are valid expressions, and they probably take a bit less "effort" creating, and there may be situations where this is a benefit. Throwing an exception
type exception from the constructor of exception
would probably not work very well, so there's one place.
However, it's probably more of a philosophical decision: Since throw
can be made to throw a any type of object, it's not a bad idea to allow it. The more restrictions you put on things in a language, the more you restrict the possible uses of a language.
From reference material about std::exception:
std::exception
All objects thrown by components of the standard library are derived from this class. Therefore, all standard exceptions can be caught by catching this type by reference.
By throwing anything else, for example NuclearPlantException
, you could handle your exceptions and the ones from the standard library separately. The standard library could throw std::invalid_argument
or std::bad_alloc
(subtypes of std::exception
) and you could throw LossOfCoolant
(a subtype of NuclearPlantException
).
So there is at least one advantage: separating standard library exceptions from your exceptions. Because you don't throw std::bad_alloc
if there's enough available space for your uranium, then any exception has a clear origin, potentially making testing and debugging easier.
Note: For more in-depth discussion see the question Should I inherit from std::exception?.
Throwing things was in C++ a decade before std::exception or even std:: became an idea. This was not removed for backward compatibility reasons.
Those who chose not use std:: certainly like it that way, and throw other exceptions, likely derived from some base class supplied by a library. It's fine until you get several exception hierarchies to deal with in client code. So new code that does not fight against using std:: entirely (setting new_handler to avoid std::bad_alloc) is likely to re-fit its exception root classes to use std::exception as base.
Throwing non-class things like ints or pointers is often advised agaist, but in a light environment can make perfect sense -- in an small embedded project leaving the exceptions enabled but throwing only an enum sounds sensible.
In general, if the language allows to throw any copyable object why restrict it? While forcing to use a special library class would be not in spirit of C++ even if we had time travel.