2

I want to throw multiple (2) different string exceptions and I want them to be caught by 2 separate catches, how can I accomplish this?

    try
    {
        std::istringstream ss2(argv[i]);

        if (!(ss2 >> l)) throw (std::string)"abc";
        if(l < 0 || l > n) throw (std::string)"xyz";
    }

    catch(std::string abc) {
        do something for abc
    }

    catch(std::string xyz){
        do something for xyz
    }

Code above would always fire the first catch and never the second.

user3369008
  • 105
  • 11
  • 2
    You simply can't. Exceptions are based on type, and you can only catch one of each type. If you have two different exceptions you want to throw, create two different types (preferably inherited from a [standard exception](http://en.cppreference.com/w/cpp/error/exception)) and catch those. – Some programmer dude Mar 08 '14 at 14:34
  • You shouldn't throw anything that doesn't derive from `std::exception`. Not only it's bad style, it usually also indicates for design flaws in your program code! – πάντα ῥεῖ Mar 08 '14 at 14:37

1 Answers1

3

The catch clause determines the exception to catch by type, not by value or an attribute of the exception object being caught.

If you would like to catch the two exceptions differently, you should create two separate exception types, rather than throwing std::string:

struct exception_one {
    std::string message;
    exception_one(const std::string& m) : message(m) {}
};
struct exception_two {
    std::string message;
    exception_two(const std::string& m) : message(m) {}
};
...
try {
    std::istringstream ss2(argv[i]);
    if (!(ss2 >> l)) throw exception_one("abc");
    if(l < 0 || l > n) throw exception_two("xyz");
}
catch(exception_one& abc) {
    do something for abc
}
catch(exception_two& xyz){
    do something for xyz
}

Note the ampersand & in the catch clause: you throw exceptions by value, and catch them by reference.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523