Sometimes I like defining my own exception types for clarity:
#include <iostream>
#include <exception>
class NegativeNumberException : public std::exception {
public:
    const char* what() const noexcept override {
        return "Negative numbers are not allowed!";
    }
};
int compare(int a, int b) {
    if (a < 0 || b < 0) throw NegativeNumberException();
    return (a > b) ? a : b;
}
int main() {
    try {
        int result = compare(-2, 3);
    } catch (const NegativeNumberException& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }
}
Custom exceptions make your error handling more descriptive.
I often do this in larger projects to differentiate types of errors.