A second error-reporting option is the "tried-and-true" traditional completion code technique used for years in C, Pascal and FORTRAN. Have your function return a special value meaning that “the function failed to execute correctly.”
In a way, this is what sqrt() does; it returns the "special" not-a-number value when its answer cannot be converted to a valid double. You can test for this value using the isnan() function in the header <cmath>. You could use the "error code" like this:
if (isnan(answer = sqrt(-1))) { /* error */ }
The isnan() function was added to C++ 11. Before that, sqrt() set the global variable errno, defined in <cerrno>, which was used like this.
double answer = sqrt(-1.0); // invalid
if (errno == EDOM) { /* invalid DOMain */ }