The question is formulated somewhat strange, so I assume that you are asking why
i % 2 ? throw ExceptionA() : throw A::B::ExceptionB();
not compiled, but
catch( A::ExceptionA& ) catch( A::B::ExceptionB& )
does.
If you look at a copy of your handy standard C ++ standard (chapter 11, paragraph 4), it says the following:
It should be noted that this is access to elements and base classes that are controlled, and not to their visibility. Member names are still visible, and implicit conversions to base classes are still considered when these members and base classes are not available.
The difference is that in the first case, you are trying to call a member A::ExceptionA or A::B::ExceptionB - the constructors for the exception. But in the output of catch, you do not get access to a member of any of them; you only get access to the type name.
However, I still think this is a bug in MSVC ++. The standard also reads in chapter 15.6, paragraph 1:
If the exception declaration in the catch clause has a class type, and the function in which the catch clause does not have access to the destructor of this class, the program is poorly formed.
which your sample seems to violate, but MSVC ++ accepts it without complaint.
source share