此代码在VS2008中生成C2248 : 'A::B::ExceptionB' : cannot access private class declared in 'class A::B'

#include <iostream>

class A
{
    class ExceptionA{};

    class B
    {
        class ExceptionB{};
        public:
        B();
    };

    public:
    A(int);

};

A::B::B()
{
    throw ExceptionB();
}

A::A(int i)
{
    i % 2 ? throw ExceptionA() : throw A::B::ExceptionB();      //  C2248 !!
}

int main()
{
    try
    {
        A a(3);
    }
    catch( A::ExceptionA& )
    {
        std::cout << "A::ExceptionA" << std::endl;
    }
    catch( A::B::ExceptionB& )
    {
        std::cout << "A::B::ExceptionB" << std::endl;
    }
}

当然,如果我在ExceptionB{}中将类B公开,则代码会编译。

但是我不明白为什么编译器不会抱怨main()中的2个catch子句,因为A::ExceptionAA中的私有(private)类,而A::B::ExceptionBA::B中的私有(private)类。

最佳答案

这个问题的措词有点奇怪,所以我假设您是在问为什么

i % 2 ? throw ExceptionA() : throw A::B::ExceptionB();

不编译,而
catch( A::ExceptionA& )
catch( A::B::ExceptionB& )

做。

如果您看一下方便的dandy C++标准的副本(第11章,第4段),则它表示以下内容:



与上面的区别在于,在第一种情况下,您尝试调用A::ExceptionAA::B::ExceptionB的成员-异常的构造函数。但是在catch语句中,您没有访问其中任何一个的成员;您只访问类型名称。

也就是说,我仍然相信这是MSVC++中的错误。该标准还在第15.6章第1节中说:



您的示例似乎违反了该规则,但MSVC++毫无保留地接受了它。

10-08 18:40