private inheritance, friends, and exception-handling
When class A privately inherits from class B it means that B is a private base class subobject of A. But not for friends, for friends it is a public sububject. And when there are multiple catch handlers the first one that matches (that is, if the exception type can be implicitly converted to the handler's parameter type) is called. So will anyone explain to me why the following code does not work as I expect? Is this behavior intended by the standard or is this a MSVC bug?
class A
{
};
class B:A //private inheritance
{
friend void g();
};
void f()
{
B b;
//A* pa = &b; // error, conversion exists, but is inaccessible
throw b;
}
void g()
{
B b;
A* pa = &b; //ok, private inheritance, but g() is B's friend so it is as though public
try
{
f();
开发者_开发技巧 }
catch(A&)
{
//WHY ISN'T THIS HANDLER INVOKED?! B&->A& conversion exists in this function
}
catch(B&)
{
}
}
int main()
{
g();
}
P.S. This is NOT real code, this is a theoretical experiment, that is, don't tell me stuff like friends are bad and composition is superior to private inheritance etc.
Thanks in advance
Nope, that's not what the standard says. It says (C++0x):
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
— the handler is a pointer or pointer to member type and E is std::nullptr_t
Rationale: Complicated implementation. You can look at this like the conversion happens somewhere between the throw and the catch, not in g itself.
精彩评论