The string literal is not std::string . You throw the first, but try to catch the last. Although a std::string can be constructed from a string literal, this will not happen in the catch clause. Conversions that are allowed in the catch clause are described in detail in [except.handle] / 3 :
A handler is a match for an exception object of type E if:
- A handler is of type cv T or cv T & and E and T are of the same type (ignoring top-level cv qualifiers) or
- the handler is of type cv T or cv T & and T is a unique public base class E, or
- the handler is of type cv T or const T & where T is a pointer or pointer to a member type, and E is a pointer or pointer to a member type that can be converted to T by one or more of
- standard pointer conversion that does not include pointer conversion to private or protected or ambiguous classes
- function pointer conversion
- qualification transformation, or
- the handler is of type cv T or const T & where T is a pointer or a pointer to a member type, and E is std :: nullptr_t.
And not one of them is used to convert literal β std::string .
This ultimately leads to the fact that this exception is unmapped and a call to the std::terminate runtime, which should happen with uncaught exceptions.
In general, it is best to use a highlighted exception type (which may be part of the hierarchy), so the type name itself reports an error. This will allow you to handle the error in more reliable ways if you need to write a handler (or a set of handlers).
If you do not want to follow standard practice for any reason, you should make the conversion one of those listed in the above brands. You can:
- Throw away
std::string literal , for example, "You cannot devide by zero!"s (note the suffix s ). - Catch a
const char* .
source share