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

C++ 为什么在随后的私有派生类中禁止简单提及基指针/引用?,c++,compiler-errors,language-lawyer,C++,Compiler Errors,Language Lawyer,这个错误对我来说似乎不合理。如果我们可以在全局范围内使用simpleB*,那么为什么不能在其私有派生类中使用呢 我们没有试图将DD*转换为B*,这是语言规则所禁止的(,是相关问题)。 请注意,如果我将B*foo()更改为int foo(),事情就会进展顺利。因此编译器显然认为B是指B的私有构造函数,而不是类型 限定B显然修复了该错误: struct B {}; struct D : private B { B* fun () { return new D; } // ok } struct

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

我们没有试图将
DD*
转换为
B*
,这是语言规则所禁止的(,是相关问题)。

请注意,如果我将
B*foo()
更改为
int foo()
,事情就会进展顺利。

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

限定
B
显然修复了该错误:

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 !
};
或者这个:

class B* foo () { return 0; }
我不知道为什么会这样,但也许这会有所帮助


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


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

< P>我最好的猜测是它不被禁止,C++在该语句中根本看不到B类型,或者更好地说,标签<代码> B/CONT>什么都没有。 一些好的读物

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

第11.1节[类别访问规范]

5/[注意:在派生类中,基类名称的查找将在声明基类的作用域中找到注入的类名,而不是基类的名称。注入的类名可能比声明基类的作用域中的基类名称更难访问。-结束注]

[示例:

-[结束示例]

我相信这与你的例子非常接近;)


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

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

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

MSVC 10.0也有同样的错误。@Yuushi,MSVC是否用?只是想知道这是否是修复此“bug”的标准方法。是的,它使用
::B*
@iammilind进行编译:正如§11.1/5;中所述,这实际上是标准处理错误的方法。)考虑到两个编译器在两个不同的平台上报告相同的错误,我认为这只是与标准或一些重要草案有关,可能与“名称解析”有关。@user1797612是的,我同意。
class A { };
class B : private A { };
class C : public B {
    A *p; // error: injected-class-name A is inaccessible
    ::A *q; // OK
};
$ 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.