10

I don't know how to phrase the question very well in a short subject line, so let me try a longer explanation. Suppose I have these exception classes:

class ExceptionTypeA : public std::runtime_error
{
    // stuff
};

class ExceptionTypeB : public std::runtime_error
{
    // stuff

    operator ExceptionTypeA() const; // conversion operator to ExceptionTypeA
};

Can I then do this, and have it trigger the catch block?

try
{
    throw ExceptionTypeB();
}
catch (ExceptionTypeA& a)
{
    // will this be triggered?
}

I'm going to guess that it will not, which is unfortunate, but I thought I'd ask, since I couldn't find any info on it on the net or on SO. And yes, I realize I could just run the program in my compiler and see what happens, but that wouldn't tell me what the standard says about this behavior, just what my compiler implements (and I don't trust it).

rmeador
  • 25,504
  • 18
  • 62
  • 103

1 Answers1

16

You cannot. Standardese at 15.3/3:

A handler is a match for an exception object of type E if

  • The handler is of type cv T or cv T& and E and T are the same type (ignoring the top-level cv- qualifiers), or
  • the handler is of type cv T or cv T& and T is an unambiguous public base class of E, or
  • the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of
    • a standard pointer conversion (4.10) not involving conversions to pointers to private or protected or ambiguous classes
    • a qualification conversion

Your desired scenario matches none of these. cv means "const and/or volatile combination"

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • does this cover pointer to members ? for instance, pointer to member data are contravariant, so `int (Base::*)` can be converted to `int (Derived::*)`. can I catch the latter if I throw the former ? gcc seems to disagree, but the standard wording is a bit unclear. – max Mar 30 '16 at 15:05