【问题标题】:g++ compilation error "... is protected from within this context" while there's no error with clangg ++编译错误“...在此上下文中受到保护”,而clang没有错误
【发布时间】:2015-10-02 01:51:45
【问题描述】:

我有以下代码:

#include <iostream>

class BaseClass {
 protected:
 static int x;
};

int BaseClass::x;

class DerivedA: public BaseClass {
 public:
     DerivedA() {
        x = 3;
     }
};    

class DerivedB: public BaseClass {
 public:
     DerivedB() {
        std::cout << DerivedA::x;
     }
};

int main(int argc, char* argv[]) {
        DerivedB b;
}

使用 g++ 编译 (g++ classtest.cpp) 我收到以下错误:

classtest.cpp:在构造函数“DeriveddB::DeriveddB()”中:
classtest.cpp:9:5: 错误:‘int BaseClass::x’受保护
int BaseClass::x;
^ classtest.cpp:25:32: 错误:在此上下文中
std::cout

当我使用 clang++ (clang++ classtest.cpp) 编译时没有错误。

为什么 g++ 返回编译错误?

我使用 g++ 5.1.0 版和 clang++ 3.6.1 版

【问题讨论】:

  • 它也在MVS2015中编译
  • 令我更惊讶的是,clang 没有抛出错误......但我可以确认,它不是。
  • @DrewDormann 为什么?我对这个错误感到惊讶:尽管有DerivedA::,但它实际上是从派生自BaseClass 的类访问BaseClass 的受保护成员。
  • @TheHumanWall: x 被声明为BaseClass 的静态成员。它是而且必须是单独定义的。
  • FWIW,这在 GCC 4.3 中确实有效,但 GCC 4.4 开始为其提供错误消息。

标签: c++ inheritance gcc clang


【解决方案1】:

GCC 错误。 [class.access.base]/p5:

当在类 N if 中命名时,成员 m 可在点 R 访问

  • m 作为N 的成员是公开的,或者
  • m 作为N 的成员是私有的,而R 出现在N 类的成员或朋友中,或者
  • m 作为N 的成员受到保护,R 出现在N 类的成员或朋友中,或在派生自N 的类P 的成员中, 其中m 作为P 的成员是公共的、私有的或受保护的,或者
  • 存在N 的基类B,可在R 访问,而m 在类B 中命名时可在R 访问。

NDerivedAmxRDerivedB 的构造函数。存在DerivedA 的基类BaseClass 可以在R 访问,并且x 在类BaseClass 中命名(即BaseClass::x)可以在R 上明显访问,所以通过第四个项目符号点,DerivedA::x 可通过R 访问。

【讨论】:

  • 那是一个糟糕的错误。尽管有问题的子弹不是最常见的,但它无论如何都不是晦涩难懂的。
  • 在 gcc 的 bugzilla 上找不到这个 - 要提交吗?
  • 感谢您的明确解释。太糟糕了,我们不能为任务提供赏金,例如打开错误报告 :)
  • 悲伤。希望这可以解释我目前在 5.2 尝试实现一些半琐碎的 crtp 时遇到的一堆难以理解的错误。目前正在下载 223 mb 的 debian 测试更新,aptitude versions 暗示现在包括 5.3。手指交叉这个恐怖解决了!
  • 令人兴奋的更新*:是的,debian testing 现在有 5.3,它立即解决了这个问题。 (好吧,它至少可以让我的代码编译;二进制文件是否有用还有待观察!)
猜你喜欢
  • 2020-10-31
  • 2011-02-05
  • 2013-04-27
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 1970-01-01
  • 2020-06-17
相关资源
最近更新 更多