14
struct B {};
struct D : private B {
  B* fun () { return new D; }  // ok
}
struct DD : public D {
  B* foo () { return 0; } // error: ‘struct B B::B’ is inaccessible !
};

这个错误对我来说似乎不合理。如果我们可以在全局范围内使用 simpleB*那么为什么不能在其私有派生类中使用呢?g++ 演示

我们不会尝试转换DD*B*,这是语言规则所禁止的(thisthisthis是相关问题)。
请注意,如果我更改B* foo()int foo(),一切都会好起来的。

4

3 回答 3

7

所以显然编译器认为B是指私有构造函数B而不是类型。

排位赛B显然修复了这个错误:

class B* foo () { return 0; }

或这个:

::B* foo () { return 0; }

我不知道为什么会这样,但也许这会有所帮助。


更新:也许它与标准的 11.2.4 有关?唯一的问题是我的标准语言不够好,无法完全理解。

(对不起图片,复制/粘贴对我不起作用)

于 2012-12-18T06:02:56.300 回答
7

在标准中快速查找注入类名称会产生:

§11.1 [class.access.spec]

5/ [注意:在派生类中,基类名称的查找将找到注入的类名称,而不是在声明它的范围内的基类名称。在声明它的范围内,注入的类名可能比基类的名称更难访问。——尾注]

[ 例子:

class A { };
class B : private A { };
class C : public B {
    A *p; // error: injected-class-name A is inaccessible
    ::A *q; // OK
};

—结束示例]

我相信这与您的示例非常接近;)


注意 clang 3.0 的堆栈,它稍微更明确:

$ clang++ -fsyntax-only test.cpp
test.cpp:6:5: error: 'B' is a private member of 'B'
    B* foo () { return 0; } // error: ‘struct B B::B’ is inaccessible !
    ^
test.cpp:2:12: note: constrained by private inheritance here
struct D : private B {
           ^~~~~~~~~
test.cpp:1:8: note: member is declared here
struct B {};
       ^
1 error generated.

在这里我们看到B是通过 访问D,而不是直接在全局命名空间中获取。

于 2012-12-18T07:45:51.517 回答
1

我最好的猜测是它不是被禁止的,C++ 根本看不到该语句中的 B 类型,或者更好的说法是标签B没有任何意义。

一些很好的阅读

于 2012-12-18T06:14:26.280 回答