访问受保护的基类类型以进行其他基类模板初始化

时间:2014-08-22 17:01:11

标签: c++ inheritance typedef protected

我有一段代码,我使用BaseFromMember成语来为我真正感兴趣的类(称为Derived)创建一个正确的继承关系。我不知道在派生类的主体之前无法访问受保护(或私有)基类类型这一事实。请参阅下面的代码:

struct BaseFromMember
{
    //protected: // comment/uncomment this line
    using T = int; // using declaration/typedef

  protected:
    BaseFromMember()
      : t_(1)
    {}

    const T& t() const { return t_; }

  private:
    const T t_;
};

template<class T>
class Base
{
  public:
    Base(const T& t)
    {}
};

class Derived
    : private BaseFromMember // private, protected, public doesn't matter here
    , public Base<typename BaseFromMember::T> // this does not work for protected type T
{
    using T = typename BaseFromMember::T; // works

  public:
    Derived()
      : BaseFromMember()
      , Base(BaseFromMember::t())
    {}
};

int main()
{
  Derived d;
}

正如预期的那样,问题不依赖于使用哪个修饰符从Derived派生BaseFromMember的事实。

但是,如果Base中的using声明是公共的,则BaseFromMember只能被初始化,否则gcc(4.8.2)和clang(3.4-1)都会出错。我认为这种行为是意外的,特别是因为typename BaseFromMember::T可以在Derived的正文中访问。

我无法在stackoverflow上找到任何相关主题。我找到了this thread,虽然我不确定它是否解决了同样的问题。

问题:我做错了什么或者我是否假设不应该假设的东西?或者这可能只是一个编译器错误?

注意:对我来说更令人不安的是,在建立typename的继承时,关键字Derived似乎没有任何影响。也许我只是做了一些非常愚蠢的事情?

注意:我不确定术语 initalization 在此上下文中是否正确,如此主题的标题中所使用的那样。如果另一个术语更合适,请告诉我。当然,我也想知道我使用的其他任何条款是否合适:)。

1 个答案:

答案 0 :(得分:0)

这不是答案。

第一步可能是将代码缩减到更短的时间。我相信这段代码仍然展示了你描述的行为:

class A {
protected:
  typedef int T;
};

template <typename T> class B {};

class C : public A, B<typename A::T> {};

实际上,这无法使用clang 3.4.1和gcc 4.8.2进行编译,而早期版本(4.5,4.6,4.7)很乐意接受它(我在C ++ 0x模式下运行每个编译器)。