【问题标题】:Why can I extend a private nested class by a template class?为什么我可以通过模板类扩展私有嵌套类?
【发布时间】:2011-06-12 23:02:36
【问题描述】:

我遇到了一个奇怪的现象,模板类似乎可以扩展私有嵌套类。

给定以下私有嵌套类:

class A {
private:
  class B {
  protected:
    void doSomething() {
      ...
    }
  };
};

以下内容未按预期编译:

class C : public A::B {
public:
  C() {
    this->doSomething();
  }
};

但是,gcc 似乎很高兴地接受了以下内容,它编译时不会发出呜咽声,并且实际上确实调用了该方法:

template<typename T>
class C : public A::B {
public:
  C() {
    this->doSomething();
  }
};

有谁知道这是使用模板时的预期行为,还是我在 gcc 中发现了一个奇怪的地方。我使用的是 4.4.5 版(Ubuntu/Linaro 4.4.4-14ubuntu5),所以我意识到我有点过时了。如果这是预期的行为,我真的很感激解释(或指向解释的指针),因为这不是我所期望的,我想了解更多。

非常感谢, 马特

【问题讨论】:

  • FWIW,这是一个可编译的测试用例:ideone.com/nJiOU
  • 感谢本。非常感谢!
  • 此错误已被报告 - 请参阅 bugzilla。 (我正要提交类似的错误报告:)

标签: c++ templates inheritance nested


【解决方案1】:

这应该是编译器错误。任何不是A朋友的类都无法访问该类,包括类模板的任何实例化。

GCC 4.2.1 和 4.6 接受该代码

Clang++ 拒绝它并显示错误消息

error: 'B' is a private member of 'A'
  struct C : A::B {

Comeau 用类似的信息拒绝了代码

error: class "A::B" (declared at line 5) is inaccessible
struct C : A::B {
              ^
      detected during instantiation of class "C<T> [with T=int]"

【讨论】:

  • 嗨,大卫。我认为这一定是编译器问题,因为我一生都无法看到是什么让类模板能够在私有嵌套类上获得可见性。我确实想知道是否有一些我以前从未听说过的模板巫术正在发生,但它只是感觉太错误了,以至于它是正确的。我非常感谢您在几个编译器上对其进行测试,因为目前我只能访问 gcc 4.4.5,因此您已经远远超出了那里的调用范围。谢谢
  • 非常感谢 Xeo 在 VS 上进行测试。我认为这不是预期的行为......但是当编译器说一件事而你认为另一件事时,它会让你停下来质疑自己。干杯
  • @Matt__E_:你可以在线使用comeau here(这一直被认为是最符合标准的编译器)。
  • 现在这是一个方便记住的链接。我知道 Comeau 非常符合标准,但不知道您可以提交代码以在线编译。为那个链接干杯。它可能会节省我将来撕掉更多的头发
  • @Matt__E_:请注意,以上链接仅供编译器使用,不会链接或执行代码。你可以以相当低的价格购买编译器前端(如果我没记错的话是 50 美元)。
猜你喜欢
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多