为什么禁止在后续的私有派生类中简单提及基指针/引用?

iam*_*ind 14 c++ compiler-errors language-lawyer

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 !
};
Run Code Online (Sandbox Code Playgroud)

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

我们是不是要转换DD*B*,这是由语言规则(禁止这个,这个,这个是相关的问题).
需要注意的是,如果我改变B* foo()int foo(),事情的罚款.

Pub*_*bby 7

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

资格B显然修复了这个错误:

class B* foo () { return 0; }
Run Code Online (Sandbox Code Playgroud)

或这个:

::B* foo () { return 0; }
Run Code Online (Sandbox Code Playgroud)

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


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

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


Mat*_* M. 7

快速查找标准中的注入类名称:

§11.1[class.access.spec]

5 / [ 注意:在派生类中,基类名称的查找将找到inject-name-name而不是声明它的作用域中基类的名称.inject-name的名称可能比声明它的作用域中的基类名称更不易访问.- 尾注 ]

[例如:

class A { };
class B : private A { };
class C : public B {
    A *p; // error: injected-class-name A is inaccessible
    ::A *q; // OK
};
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

我相信这与你的榜样非常接近;)


注意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.
Run Code Online (Sandbox Code Playgroud)

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